1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 19:50:24 +02:00

* stime.c (scm_strftime): Recognize a return value of zero from

strftime as buffer overflow and take care to detect a valid zero
length result regardless.  Thanks to David Barts!
This commit is contained in:
Marius Vollmer 2000-07-23 23:12:39 +00:00
parent 23d919087e
commit a15e6dcc8f

View file

@ -62,6 +62,10 @@
# include <sys/types.h>
# endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
# ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
@ -560,7 +564,7 @@ SCM_DEFINE (scm_strftime, "strftime", 2, 0, 0,
char *tbuf;
int size = 50;
char *fmt;
char *fmt, *myfmt;
int len;
SCM result;
@ -571,6 +575,16 @@ SCM_DEFINE (scm_strftime, "strftime", 2, 0, 0,
fmt = SCM_ROCHARS (format);
len = SCM_ROLENGTH (format);
/* Ugly hack: strftime can return 0 if its buffer is too small,
but some valid time strings (e.g. "%p") can sometimes produce
a zero-byte output string! Workaround is to prepend a junk
character to the format string, so that valid returns are always
nonzero. */
myfmt = SCM_MUST_MALLOC (len+2);
*myfmt = 'x';
strncpy(myfmt+1, fmt, len);
myfmt[len+1] = 0;
tbuf = SCM_MUST_MALLOC (size);
{
#if !defined (HAVE_TM_ZONE)
@ -603,7 +617,10 @@ SCM_DEFINE (scm_strftime, "strftime", 2, 0, 0,
tzset ();
#endif
while ((len = strftime (tbuf, size, fmt, &t)) == size)
/* POSIX says strftime returns 0 on buffer overrun, but old
systems (i.e. libc 4 on GNU/Linux) might return `size' in that
case. */
while ((len = strftime (tbuf, size, myfmt, &t)) == 0 || len == size)
{
scm_must_free (tbuf);
size *= 2;
@ -619,8 +636,9 @@ SCM_DEFINE (scm_strftime, "strftime", 2, 0, 0,
#endif
}
result = scm_makfromstr (tbuf, len, 0);
result = scm_makfromstr (tbuf+1, len-1, 0);
scm_must_free (tbuf);
scm_must_free(myfmt);
return result;
}
#undef FUNC_NAME