diff options
author | dana <dana@dana.is> | 2018-12-29 05:22:34 -0600 |
---|---|---|
committer | dana <dana@dana.is> | 2018-12-29 05:24:25 -0600 |
commit | 162c198aabcdbe3795d34142c4707649f60fe499 (patch) | |
tree | 609bf48c39b34c288be4b3580bd9d70d1d4e583a /Src/utils.c | |
parent | f64cd71d442b0b7152131282dd7567be010edb78 (diff) | |
download | zsh-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.c | 21 |
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++ = '%'; |