mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-01 05:16:05 +01:00
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.
This commit is contained in:
parent
5292d60eb1
commit
f8164fb647
8 changed files with 61 additions and 16 deletions
|
@ -1,5 +1,11 @@
|
||||||
2015-08-18 Peter Stephenson <p.stephenson@samsung.com>
|
2015-08-18 Peter Stephenson <p.stephenson@samsung.com>
|
||||||
|
|
||||||
|
* 36227: Src/Builtins/sched.c, Src/Modules/datetime.c,
|
||||||
|
Src/Modules/stat.c, Src/builtin.c, Src/prompt.c, Src/utils.c,
|
||||||
|
Src/watch.c: real fix for metafication problem in ztrftime:
|
||||||
|
unmetafy fmt on input and metafy return value with correct
|
||||||
|
length.
|
||||||
|
|
||||||
* unposted: revert 36222, not the correct fix.
|
* unposted: revert 36222, not the correct fix.
|
||||||
|
|
||||||
* 36222: Src/Modules/datetime.c: unmetafy output from strftime.
|
* 36222: Src/Modules/datetime.c: unmetafy output from strftime.
|
||||||
|
|
|
@ -220,7 +220,8 @@ bin_sched(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
|
||||||
endstr = "-- ";
|
endstr = "-- ";
|
||||||
else
|
else
|
||||||
endstr = "";
|
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;
|
return 0;
|
||||||
} else if (!argptr[1]) {
|
} else if (!argptr[1]) {
|
||||||
|
|
|
@ -98,7 +98,7 @@ reverse_strftime(char *nam, char **argv, char *scalar, int quiet)
|
||||||
static int
|
static int
|
||||||
output_strftime(char *nam, char **argv, Options ops, UNUSED(int func))
|
output_strftime(char *nam, char **argv, Options ops, UNUSED(int func))
|
||||||
{
|
{
|
||||||
int bufsize, x;
|
int bufsize, x, len;
|
||||||
char *endptr = NULL, *scalar = NULL, *buffer;
|
char *endptr = NULL, *scalar = NULL, *buffer;
|
||||||
time_t secs;
|
time_t secs;
|
||||||
struct tm *t;
|
struct tm *t;
|
||||||
|
@ -131,16 +131,19 @@ output_strftime(char *nam, char **argv, Options ops, UNUSED(int func))
|
||||||
bufsize = strlen(argv[0]) * 8;
|
bufsize = strlen(argv[0]) * 8;
|
||||||
buffer = zalloc(bufsize);
|
buffer = zalloc(bufsize);
|
||||||
|
|
||||||
|
len = 0;
|
||||||
for (x=0; x < 4; x++) {
|
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;
|
break;
|
||||||
buffer = zrealloc(buffer, bufsize *= 2);
|
buffer = zrealloc(buffer, bufsize *= 2);
|
||||||
}
|
}
|
||||||
|
DPUTS(len < 0, "bad output from ztrftime");
|
||||||
|
|
||||||
if (scalar) {
|
if (scalar) {
|
||||||
setsparam(scalar, metafy(buffer, -1, META_DUP));
|
setsparam(scalar, metafy(buffer, len, META_DUP));
|
||||||
} else {
|
} else {
|
||||||
printf("%s\n", buffer);
|
fwrite(buffer, 1, len, stdout);
|
||||||
|
putchar('\n');
|
||||||
}
|
}
|
||||||
zfree(buffer, bufsize);
|
zfree(buffer, bufsize);
|
||||||
|
|
||||||
|
|
|
@ -197,8 +197,11 @@ stattimeprint(time_t tim, char *outbuf, int flags)
|
||||||
}
|
}
|
||||||
if (flags & STF_STRING) {
|
if (flags & STF_STRING) {
|
||||||
char *oend = outbuf + strlen(outbuf);
|
char *oend = outbuf + strlen(outbuf);
|
||||||
ztrftime(oend, 40, timefmt, (flags & STF_GMT) ? gmtime(&tim) :
|
/* Where the heck does "40" come from? */
|
||||||
localtime(&tim), 0L);
|
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)
|
if (flags & STF_RAW)
|
||||||
strcat(oend, ")");
|
strcat(oend, ")");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1783,9 +1783,12 @@ fclist(FILE *f, Options ops, zlong first, zlong last,
|
||||||
command, if required */
|
command, if required */
|
||||||
if (tdfmt != NULL) {
|
if (tdfmt != NULL) {
|
||||||
struct tm *ltm;
|
struct tm *ltm;
|
||||||
|
int len;
|
||||||
ltm = localtime(&ent->stim);
|
ltm = localtime(&ent->stim);
|
||||||
if (ztrftime(timebuf, 256, tdfmt, ltm, 0L))
|
if ((len = ztrftime(timebuf, 256, tdfmt, ltm, 0L)) >= 0) {
|
||||||
fprintf(f, "%s ", timebuf);
|
fwrite(timebuf, 1, len, f);
|
||||||
|
fprintf(f, " ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* display the time taken by the command, if required */
|
/* display the time taken by the command, if required */
|
||||||
if (OPT_ISSET(ops,'D')) {
|
if (OPT_ISSET(ops,'D')) {
|
||||||
|
|
|
@ -271,7 +271,7 @@ static int
|
||||||
putpromptchar(int doprint, int endchar, unsigned int *txtchangep)
|
putpromptchar(int doprint, int endchar, unsigned int *txtchangep)
|
||||||
{
|
{
|
||||||
char *ss, *hostnam;
|
char *ss, *hostnam;
|
||||||
int t0, arg, test, sep, j, numjobs;
|
int t0, arg, test, sep, j, numjobs, len;
|
||||||
struct tm *tm;
|
struct tm *tm;
|
||||||
struct timezone dummy_tz;
|
struct timezone dummy_tz;
|
||||||
struct timeval tv;
|
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) {
|
for(j = 0, t0 = strlen(tmfmt)*8; j < 3; j++, t0*=2) {
|
||||||
addbufspc(t0);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
/* There is enough room for this because addbufspc(t0)
|
/* There is enough room for this because addbufspc(t0)
|
||||||
* allocates room for t0 * 2 bytes. */
|
* 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);
|
bv->bp += strlen(bv->bp);
|
||||||
zsfree(tmbuf);
|
zsfree(tmbuf);
|
||||||
break;
|
break;
|
||||||
|
|
30
Src/utils.c
30
Src/utils.c
|
@ -2878,6 +2878,10 @@ ztrftimebuf(int *bufsizeptr, int decr)
|
||||||
* not enough memory --- and return -1. Not guaranteed to be portable,
|
* not enough memory --- and return -1. Not guaranteed to be portable,
|
||||||
* since the strftime() interface doesn't make any guarantees about
|
* since the strftime() interface doesn't make any guarantees about
|
||||||
* the state of the buffer if it returns zero.
|
* 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;
|
char *origbuf = buf;
|
||||||
|
|
||||||
|
|
||||||
while (*fmt)
|
while (*fmt) {
|
||||||
if (*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 strip;
|
||||||
int digs = 3;
|
int digs = 3;
|
||||||
|
|
||||||
|
@ -3083,8 +3093,21 @@ strftimehandling:
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int size = fmt - fmtstart;
|
int size = fmt - fmtstart;
|
||||||
char *tmp = zhalloc(size + 1);
|
char *tmp, *last;
|
||||||
|
tmp = zhalloc(size + 1);
|
||||||
strncpy(tmp, fmtstart, size);
|
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';
|
tmp[size] = '\0';
|
||||||
*buf = '\1';
|
*buf = '\1';
|
||||||
if (!strftime(buf, bufsize + 2, tmp, tm))
|
if (!strftime(buf, bufsize + 2, tmp, tm))
|
||||||
|
@ -3107,6 +3130,7 @@ strftimehandling:
|
||||||
return -1;
|
return -1;
|
||||||
*buf++ = *fmt++;
|
*buf++ = *fmt++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
*buf = '\0';
|
*buf = '\0';
|
||||||
return buf - origbuf;
|
return buf - origbuf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,6 +237,7 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini)
|
||||||
time_t timet;
|
time_t timet;
|
||||||
struct tm *tm;
|
struct tm *tm;
|
||||||
char *fm2;
|
char *fm2;
|
||||||
|
int len;
|
||||||
# ifdef WATCH_UTMP_UT_HOST
|
# ifdef WATCH_UTMP_UT_HOST
|
||||||
char *p;
|
char *p;
|
||||||
int i;
|
int i;
|
||||||
|
@ -330,7 +331,9 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini)
|
||||||
}
|
}
|
||||||
timet = getlogtime(u, inout);
|
timet = getlogtime(u, inout);
|
||||||
tm = localtime(&timet);
|
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);
|
printf("%s", (*buf == ' ') ? buf + 1 : buf);
|
||||||
break;
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
|
|
Loading…
Reference in a new issue