summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
authorPeter Stephenson <pws@zsh.org>2015-08-18 16:20:48 +0100
committerPeter Stephenson <pws@zsh.org>2015-08-18 16:20:48 +0100
commitf8164fb647a8e7947cfde137ddd9517b2fab51c4 (patch)
tree493d0eaddda9ee2e14772282db0a70aa07903cf3 /Src
parent5292d60eb1b2ed5e021e3ee3d05bf08136757ac4 (diff)
downloadzsh-f8164fb647a8e7947cfde137ddd9517b2fab51c4.tar.gz
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')
-rw-r--r--Src/Builtins/sched.c3
-rw-r--r--Src/Modules/datetime.c11
-rw-r--r--Src/Modules/stat.c7
-rw-r--r--Src/builtin.c7
-rw-r--r--Src/prompt.c8
-rw-r--r--Src/utils.c30
-rw-r--r--Src/watch.c5
7 files changed, 55 insertions, 16 deletions
diff --git a/Src/Builtins/sched.c b/Src/Builtins/sched.c
index bcf7661f4..5d5dac6b7 100644
--- a/Src/Builtins/sched.c
+++ b/Src/Builtins/sched.c
@@ -220,7 +220,8 @@ bin_sched(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
endstr = "-- ";
else
endstr = "";
- printf("%3d %s %s%s%s\n", sn, tbuf, flagstr, endstr, sch->cmd);
+ printf("%3d %s %s%s%s\n", sn, tbuf, flagstr, endstr,
+ unmeta(sch->cmd));
}
return 0;
} else if (!argptr[1]) {
diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c
index d9416679f..86c61cf1c 100644
--- a/Src/Modules/datetime.c
+++ b/Src/Modules/datetime.c
@@ -98,7 +98,7 @@ reverse_strftime(char *nam, char **argv, char *scalar, int quiet)
static int
output_strftime(char *nam, char **argv, Options ops, UNUSED(int func))
{
- int bufsize, x;
+ int bufsize, x, len;
char *endptr = NULL, *scalar = NULL, *buffer;
time_t secs;
struct tm *t;
@@ -131,16 +131,19 @@ output_strftime(char *nam, char **argv, Options ops, UNUSED(int func))
bufsize = strlen(argv[0]) * 8;
buffer = zalloc(bufsize);
+ len = 0;
for (x=0; x < 4; x++) {
- if (ztrftime(buffer, bufsize, argv[0], t, 0L) >= 0)
+ if ((len = ztrftime(buffer, bufsize, argv[0], t, 0L)) >= 0)
break;
buffer = zrealloc(buffer, bufsize *= 2);
}
+ DPUTS(len < 0, "bad output from ztrftime");
if (scalar) {
- setsparam(scalar, metafy(buffer, -1, META_DUP));
+ setsparam(scalar, metafy(buffer, len, META_DUP));
} else {
- printf("%s\n", buffer);
+ fwrite(buffer, 1, len, stdout);
+ putchar('\n');
}
zfree(buffer, bufsize);
diff --git a/Src/Modules/stat.c b/Src/Modules/stat.c
index 6fc53894c..396177149 100644
--- a/Src/Modules/stat.c
+++ b/Src/Modules/stat.c
@@ -197,8 +197,11 @@ stattimeprint(time_t tim, char *outbuf, int flags)
}
if (flags & STF_STRING) {
char *oend = outbuf + strlen(outbuf);
- ztrftime(oend, 40, timefmt, (flags & STF_GMT) ? gmtime(&tim) :
- localtime(&tim), 0L);
+ /* Where the heck does "40" come from? */
+ int len = ztrftime(oend, 40, timefmt, (flags & STF_GMT) ? gmtime(&tim) :
+ localtime(&tim), 0L);
+ if (len > 0)
+ metafy(oend, len, META_NOALLOC);
if (flags & STF_RAW)
strcat(oend, ")");
}
diff --git a/Src/builtin.c b/Src/builtin.c
index 4a97a3163..572a0dd68 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -1783,9 +1783,12 @@ fclist(FILE *f, Options ops, zlong first, zlong last,
command, if required */
if (tdfmt != NULL) {
struct tm *ltm;
+ int len;
ltm = localtime(&ent->stim);
- if (ztrftime(timebuf, 256, tdfmt, ltm, 0L))
- fprintf(f, "%s ", timebuf);
+ if ((len = ztrftime(timebuf, 256, tdfmt, ltm, 0L)) >= 0) {
+ fwrite(timebuf, 1, len, f);
+ fprintf(f, " ");
+ }
}
/* display the time taken by the command, if required */
if (OPT_ISSET(ops,'D')) {
diff --git a/Src/prompt.c b/Src/prompt.c
index 9e8589d5b..be067ee7e 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -271,7 +271,7 @@ static int
putpromptchar(int doprint, int endchar, unsigned int *txtchangep)
{
char *ss, *hostnam;
- int t0, arg, test, sep, j, numjobs;
+ int t0, arg, test, sep, j, numjobs, len;
struct tm *tm;
struct timezone dummy_tz;
struct timeval tv;
@@ -673,12 +673,14 @@ putpromptchar(int doprint, int endchar, unsigned int *txtchangep)
*/
for(j = 0, t0 = strlen(tmfmt)*8; j < 3; j++, t0*=2) {
addbufspc(t0);
- if (ztrftime(bv->bp, t0, tmfmt, tm, tv.tv_usec) >= 0)
+ if ((len = ztrftime(bv->bp, t0, tmfmt, tm, tv.tv_usec))
+ >= 0)
break;
}
/* There is enough room for this because addbufspc(t0)
* allocates room for t0 * 2 bytes. */
- metafy(bv->bp, -1, META_NOALLOC);
+ if (len >= 0)
+ metafy(bv->bp, len, META_NOALLOC);
bv->bp += strlen(bv->bp);
zsfree(tmbuf);
break;
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;
}
diff --git a/Src/watch.c b/Src/watch.c
index e1bdaa4a0..c804913ad 100644
--- a/Src/watch.c
+++ b/Src/watch.c
@@ -237,6 +237,7 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini)
time_t timet;
struct tm *tm;
char *fm2;
+ int len;
# ifdef WATCH_UTMP_UT_HOST
char *p;
int i;
@@ -330,7 +331,9 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini)
}
timet = getlogtime(u, inout);
tm = localtime(&timet);
- ztrftime(buf, 40, fm2, tm, 0L);
+ len = ztrftime(buf, 40, fm2, tm, 0L);
+ if (len > 0)
+ metafy(buf, len, META_NOALLOC);
printf("%s", (*buf == ' ') ? buf + 1 : buf);
break;
case '%':