mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-16 12:21:18 +02:00
19168: Various problems with size of buffers and pointer usage in ztrftime
This commit is contained in:
parent
bbc409eefe
commit
ed6a7ba60e
4 changed files with 79 additions and 19 deletions
|
@ -1,5 +1,9 @@
|
|||
2003-10-06 Peter Stephenson <pws@pwstephenson.fsnet.co.uk>
|
||||
|
||||
* 19168: Src/prompt.c, Src/utils.c, Src/Modules/datetime.c:
|
||||
various problems with size of buffers and pointer usage
|
||||
in ztrftime().
|
||||
|
||||
* 19167: Src/glob.c, Test/E01options.ztst: NULL at start
|
||||
of BRACE_CCL range didn't work.
|
||||
|
||||
|
|
|
@ -35,10 +35,9 @@ static int
|
|||
bin_strftime(char *nam, char **argv, Options ops, int func)
|
||||
{
|
||||
int bufsize, x;
|
||||
char *endptr = NULL, *buffer = NULL;
|
||||
char *endptr = NULL, *buffer;
|
||||
time_t secs;
|
||||
struct tm *t;
|
||||
int size;
|
||||
|
||||
secs = (time_t)strtoul(argv[1], &endptr, 10);
|
||||
if (secs == ULONG_MAX) {
|
||||
|
@ -51,15 +50,17 @@ bin_strftime(char *nam, char **argv, Options ops, int func)
|
|||
|
||||
t = localtime(&secs);
|
||||
bufsize = strlen(argv[0]) * 2;
|
||||
buffer = zalloc(bufsize);
|
||||
|
||||
for (x=1;x<4;x++) {
|
||||
buffer = zrealloc(buffer, bufsize * x);
|
||||
size = ztrftime(buffer, bufsize * x, argv[0], t);
|
||||
if (size) x = 4;
|
||||
for (x=0; x < 4; x++) {
|
||||
if (ztrftime(buffer, bufsize, argv[0], t))
|
||||
break;
|
||||
buffer = zrealloc(buffer, bufsize *= 2);
|
||||
}
|
||||
|
||||
printf("%s\n", buffer);
|
||||
|
||||
zfree(buffer, bufsize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
11
Src/prompt.c
11
Src/prompt.c
|
@ -500,18 +500,23 @@ putpromptchar(int doprint, int endchar)
|
|||
tmfmt = "%m/%d/%y";
|
||||
break;
|
||||
case 'D':
|
||||
if (fm[1] == '{') /*}*/ {
|
||||
if (fm[1] == '{' /*}*/) {
|
||||
for (ss = fm + 2; *ss && *ss != /*{*/ '}'; ss++)
|
||||
if(*ss == '\\' && ss[1])
|
||||
ss++;
|
||||
dd = tmfmt = tmbuf = zalloc(ss - fm);
|
||||
for (ss = fm + 2; *ss && *ss != /*{*/ '}'; ss++) {
|
||||
for (ss = fm + 2; *ss && *ss != /*{*/ '}';
|
||||
ss++) {
|
||||
if(*ss == '\\' && ss[1])
|
||||
ss++;
|
||||
*dd++ = *ss;
|
||||
}
|
||||
*dd = 0;
|
||||
fm = ss - !*ss;
|
||||
if (!*tmfmt) {
|
||||
free(tmbuf);
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
tmfmt = "%y-%m-%d";
|
||||
break;
|
||||
|
@ -523,7 +528,7 @@ putpromptchar(int doprint, int endchar)
|
|||
tm = localtime(&timet);
|
||||
for(t0=80; ; t0*=2) {
|
||||
addbufspc(t0);
|
||||
if(ztrftime(bp, t0, tmfmt, tm) != t0)
|
||||
if (ztrftime(bp, t0, tmfmt, tm))
|
||||
break;
|
||||
}
|
||||
bp += strlen(bp);
|
||||
|
|
68
Src/utils.c
68
Src/utils.c
|
@ -1685,20 +1685,42 @@ spckword(char **s, int hist, int cmd, int ask)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper for ztrftime. Called with a pointer to the length left
|
||||
* in the buffer, and a new string length to decrement from that.
|
||||
* Returns 0 if the new length fits, 1 otherwise. We assume a terminating
|
||||
* NUL and return 1 if that doesn't fit.
|
||||
*/
|
||||
|
||||
/**/
|
||||
static int
|
||||
ztrftimebuf(int *bufsizeptr, int decr)
|
||||
{
|
||||
if (*bufsizeptr <= decr)
|
||||
return 1;
|
||||
*bufsizeptr -= decr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Like the system function, this returns the number of characters
|
||||
* copied, not including the terminating NUL. This may be zero
|
||||
* if the string didn't fit.
|
||||
*/
|
||||
|
||||
/**/
|
||||
mod_export int
|
||||
ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
|
||||
{
|
||||
int hr12;
|
||||
int hr12, decr;
|
||||
#ifndef HAVE_STRFTIME
|
||||
static char *astr[] =
|
||||
{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
||||
static char *estr[] =
|
||||
{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
|
||||
"Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
#else
|
||||
char *origbuf = buf;
|
||||
#endif
|
||||
char *origbuf = buf;
|
||||
char tmp[3];
|
||||
|
||||
|
||||
|
@ -1707,6 +1729,14 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
|
|||
while (*fmt)
|
||||
if (*fmt == '%') {
|
||||
fmt++;
|
||||
/*
|
||||
* Assume this format will take up at least two
|
||||
* characters. Not always true, but if that matters
|
||||
* we are so close to the edge it's not a big deal.
|
||||
* Fix up some longer cases specially when we get to them.
|
||||
*/
|
||||
if (ztrftimebuf(&bufsize, 2))
|
||||
return 0;
|
||||
switch (*fmt++) {
|
||||
case 'd':
|
||||
*buf++ = '0' + tm->tm_mday / 10;
|
||||
|
@ -1734,9 +1764,10 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
|
|||
if (hr12 == 0)
|
||||
hr12 = 12;
|
||||
if (hr12 > 9)
|
||||
*buf++ = '1';
|
||||
*buf++ = '1';
|
||||
else if (fmt[-1] == 'l')
|
||||
*buf++ = ' ';
|
||||
*buf++ = ' ';
|
||||
|
||||
*buf++ = '0' + (hr12 % 10);
|
||||
break;
|
||||
case 'm':
|
||||
|
@ -1755,11 +1786,20 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
|
|||
*buf++ = '0' + (tm->tm_year / 10) % 10;
|
||||
*buf++ = '0' + tm->tm_year % 10;
|
||||
break;
|
||||
case '\0':
|
||||
/* Guard against premature end of string */
|
||||
*buf++ = '%';
|
||||
fmt--;
|
||||
break;
|
||||
#ifndef HAVE_STRFTIME
|
||||
case 'a':
|
||||
if (ztrftimebuf(&bufsize, strlen(astr[tm->tm_wday]) - 2))
|
||||
return 0;
|
||||
strucpy(&buf, astr[tm->tm_wday]);
|
||||
break;
|
||||
case 'b':
|
||||
if (ztrftimebuf(&bufsize, strlen(estr[tm->tm_mon]) - 2))
|
||||
return 0;
|
||||
strucpy(&buf, estr[tm->tm_mon]);
|
||||
break;
|
||||
case 'p':
|
||||
|
@ -1772,17 +1812,27 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
|
|||
*buf++ = fmt[-1];
|
||||
#else
|
||||
default:
|
||||
/*
|
||||
* Remember we've already allowed for two characters
|
||||
* in the accounting in bufsize (but nowhere else).
|
||||
*/
|
||||
*buf = '\0';
|
||||
tmp[1] = fmt[-1];
|
||||
strftime(buf, bufsize - strlen(origbuf), tmp, tm);
|
||||
buf += strlen(buf);
|
||||
if (!strftime(buf, bufsize + 2, tmp, tm))
|
||||
return 0;
|
||||
decr = strlen(buf);
|
||||
buf += decr;
|
||||
bufsize -= decr - 2;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
if (ztrftimebuf(&bufsize, 1))
|
||||
return 0;
|
||||
*buf++ = *fmt++;
|
||||
}
|
||||
*buf = '\0';
|
||||
return 0;
|
||||
return buf - origbuf;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
Loading…
Reference in a new issue