diff options
author | Peter Stephenson <pws@zsh.org> | 2015-08-18 16:20:48 +0100 |
---|---|---|
committer | Peter Stephenson <pws@zsh.org> | 2015-08-18 16:20:48 +0100 |
commit | f8164fb647a8e7947cfde137ddd9517b2fab51c4 (patch) | |
tree | 493d0eaddda9ee2e14772282db0a70aa07903cf3 /Src/utils.c | |
parent | 5292d60eb1b2ed5e021e3ee3d05bf08136757ac4 (diff) | |
download | zsh-f8164fb647a8e7947cfde137ddd9517b2fab51c4.tar.gz zsh-f8164fb647a8e7947cfde137ddd9517b2fab51c4.tar.xz zsh-f8164fb647a8e7947cfde137ddd9517b2fab51c4.zip |
36227: attempt to fix metafication problem with ztrftime.
fmt is treated as metafied on entry; use returned length to ensure we metafy or output the correct length if there are embedded nulls.
Diffstat (limited to 'Src/utils.c')
-rw-r--r-- | Src/utils.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/Src/utils.c b/Src/utils.c index 236661a9f..20e01a207 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -2878,6 +2878,10 @@ ztrftimebuf(int *bufsizeptr, int decr) * not enough memory --- and return -1. Not guaranteed to be portable, * since the strftime() interface doesn't make any guarantees about * the state of the buffer if it returns zero. + * + * fmt is metafied, but we need to unmetafy it on the fly to + * pass into strftime / combine with the output from strftime. + * The return value in buf is not metafied. */ /**/ @@ -2898,8 +2902,14 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm, long usec) char *origbuf = buf; - while (*fmt) - if (*fmt == '%') { + while (*fmt) { + if (*fmt == Meta) { + int chr = fmt[1] ^ 32; + if (ztrftimebuf(&bufsize, 1)) + return -1; + *buf++ = chr; + fmt += 2; + } else if (*fmt == '%') { int strip; int digs = 3; @@ -3083,8 +3093,21 @@ strftimehandling: */ { int size = fmt - fmtstart; - char *tmp = zhalloc(size + 1); + char *tmp, *last; + tmp = zhalloc(size + 1); strncpy(tmp, fmtstart, size); + last = fmt-1; + if (*last == Meta) { + /* + * This is for consistency in counting: + * a metafiable character isn't actually + * a valid strftime descriptor. + * + * Previous characters were explicitly checked, + * so can't be metafied. + */ + *last = *++fmt ^ 32; + } tmp[size] = '\0'; *buf = '\1'; if (!strftime(buf, bufsize + 2, tmp, tm)) @@ -3107,6 +3130,7 @@ strftimehandling: return -1; *buf++ = *fmt++; } + } *buf = '\0'; return buf - origbuf; } |