mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +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:
parent
23d919087e
commit
a15e6dcc8f
1 changed files with 21 additions and 3 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue