* time/asctime.c (asctime_internal): New function, derived from
	asctime_r.  Takes additional parameter which is the buffer length.
	Use snprintf instead sprintf, if it overflows, fail.
	(asctime_r): Call asctime_internal with 26 as buffer length.
	(asctime): Call asctime_internal with length of internal buffer.
	* time/Makefile (tests): Add bug-asctime_r.
	* time/bug-asctime_r.c: New file.
This commit is contained in:
Ulrich Drepper 2005-10-14 15:17:40 +00:00
parent 576c845148
commit ce982312e8
5 changed files with 69 additions and 18 deletions

View File

@ -1,5 +1,14 @@
2005-10-14 Ulrich Drepper <drepper@redhat.com>
[BZ #1460]
* time/asctime.c (asctime_internal): New function, derived from
asctime_r. Takes additional parameter which is the buffer length.
Use snprintf instead sprintf, if it overflows, fail.
(asctime_r): Call asctime_internal with 26 as buffer length.
(asctime): Call asctime_internal with length of internal buffer.
* time/Makefile (tests): Add bug-asctime_r.
* time/bug-asctime_r.c: New file.
[BZ #1459]
* time/asctime.c (__asctime_r): Check for tm_year computation to
overflow and fail in this case.

View File

@ -35,7 +35,7 @@ distribute := datemsk
tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
tst-mktime3 tst-strptime2 bug-asctime
tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r
include ../Rules

View File

@ -31,17 +31,9 @@ extern const struct locale_data _nl_C_LC_TIME attribute_hidden;
static const char format[] = "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n";
static char result[ 3+1+ 3+1+20+1+20+1+20+1+20+1+20+1 + 1];
/* Returns a string of the form "Day Mon dd hh:mm:ss yyyy\n"
which is the representation of TP in that form. */
char *
asctime (const struct tm *tp)
{
return __asctime_r (tp, result);
}
libc_hidden_def (asctime)
char *
__asctime_r (const struct tm *tp, char *buf)
static char *
asctime_internal (const struct tm *tp, char *buf, size_t buflen)
{
if (tp == NULL)
{
@ -58,19 +50,42 @@ __asctime_r (const struct tm *tp, char *buf)
a buffer size would be passed. */
if (__builtin_expect (tp->tm_year > INT_MAX - 1900, 0))
{
eoverflow:
__set_errno (EOVERFLOW);
return NULL;
}
if (sprintf (buf, format,
int n = snprintf (buf, buflen, format,
(tp->tm_wday < 0 || tp->tm_wday >= 7 ?
"???" : ab_day_name (tp->tm_wday)),
(tp->tm_mon < 0 || tp->tm_mon >= 12 ?
"???" : ab_month_name (tp->tm_mon)),
tp->tm_mday, tp->tm_hour, tp->tm_min,
tp->tm_sec, 1900 + tp->tm_year) < 0)
tp->tm_sec, 1900 + tp->tm_year);
if (n < 0)
return NULL;
if (n >= buflen)
goto eoverflow;
return buf;
}
/* Like asctime, but write result to the user supplied buffer. The
buffer is only guaranteed to be 26 bytes in length. */
char *
__asctime_r (const struct tm *tp, char *buf)
{
return asctime_internal (tp, buf, 26);
}
weak_alias (__asctime_r, asctime_r)
/* Returns a string of the form "Day Mon dd hh:mm:ss yyyy\n"
which is the representation of TP in that form. */
char *
asctime (const struct tm *tp)
{
return asctime_internal (tp, result, sizeof (result));
}
libc_hidden_def (asctime)

View File

@ -19,6 +19,7 @@ do_test (void)
result = 1;
}
char buf[1000];
errno = 0;
s = asctime_r (tp, buf);
if (s != NULL || errno != EOVERFLOW)
{

26
time/bug-asctime_r.c Normal file
View File

@ -0,0 +1,26 @@
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <time.h>
static int
do_test (void)
{
int result = 0;
time_t t = time (NULL);
struct tm *tp = localtime (&t);
tp->tm_year = 10000 - 1900;
char buf[1000];
errno = 0;
char *s = asctime_r (tp, buf);
if (s != NULL || errno != EOVERFLOW)
{
puts ("asctime_r did not fail correctly");
result = 1;
}
return result;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"