about summary refs log tree commit diff
path: root/Src/utils.c
diff options
context:
space:
mode:
authordana <dana@dana.is>2018-12-29 05:22:34 -0600
committerdana <dana@dana.is>2018-12-29 05:24:25 -0600
commit162c198aabcdbe3795d34142c4707649f60fe499 (patch)
tree609bf48c39b34c288be4b3580bd9d70d1d4e583a /Src/utils.c
parentf64cd71d442b0b7152131282dd7567be010edb78 (diff)
downloadzsh-162c198aabcdbe3795d34142c4707649f60fe499.tar.gz
zsh-162c198aabcdbe3795d34142c4707649f60fe499.tar.xz
zsh-162c198aabcdbe3795d34142c4707649f60fe499.zip
43953: Fix rounding/truncation error in %. time-format specifier
Also fixes an issue where %. couldn't be used more than once in a format
string without strange results

Tweaked very slightly per workers/43954
Diffstat (limited to 'Src/utils.c')
-rw-r--r--Src/utils.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/Src/utils.c b/Src/utils.c
index e43a3cdb4..0969cef37 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -3334,19 +3334,28 @@ morefmt:
 #endif
 	    switch (*fmt++) {
 	    case '.':
-		if (ztrftimebuf(&bufsize, digs))
-		    return -1;
+	    {
+		long fnsec = nsec;
 		if (digs > 9)
 		    digs = 9;
+		if (ztrftimebuf(&bufsize, digs))
+		    return -1;
 		if (digs < 9) {
 		    int trunc;
-		    for (trunc = 8 - digs; trunc; trunc--)
-			nsec /= 10;
-		    nsec = (nsec + 8) / 10;
+		    long max = 100000000;
+		    for (trunc = 8 - digs; trunc; trunc--) {
+			max /= 10;
+			fnsec /= 10;
+		    }
+		    max -= 1;
+		    fnsec = (fnsec + 5) / 10;
+		    if (fnsec > max)
+			fnsec = max;
 		}
-		sprintf(buf, "%0*ld", digs, nsec);
+		sprintf(buf, "%0*ld", digs, fnsec);
 		buf += digs;
 		break;
+	    }
 	    case '\0':
 		/* Guard against premature end of string */
 		*buf++ = '%';