From f8164fb647a8e7947cfde137ddd9517b2fab51c4 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 18 Aug 2015 16:20:48 +0100 Subject: 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. --- Src/utils.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'Src/utils.c') 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; } -- cgit 1.4.1