mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-26 23:10:06 +00:00
[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.
This commit is contained in:
parent
576c845148
commit
ce982312e8
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
26
time/bug-asctime_r.c
Normal 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"
|
Loading…
Reference in New Issue
Block a user