mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-09 14:50:05 +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>
|
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]
|
[BZ #1459]
|
||||||
* time/asctime.c (__asctime_r): Check for tm_year computation to
|
* time/asctime.c (__asctime_r): Check for tm_year computation to
|
||||||
overflow and fail in this case.
|
overflow and fail in this case.
|
||||||
|
@ -35,7 +35,7 @@ distribute := datemsk
|
|||||||
|
|
||||||
tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
|
tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
|
||||||
tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
|
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
|
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 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];
|
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 *
|
static char *
|
||||||
__asctime_r (const struct tm *tp, char *buf)
|
asctime_internal (const struct tm *tp, char *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
if (tp == NULL)
|
if (tp == NULL)
|
||||||
{
|
{
|
||||||
@ -58,19 +50,42 @@ __asctime_r (const struct tm *tp, char *buf)
|
|||||||
a buffer size would be passed. */
|
a buffer size would be passed. */
|
||||||
if (__builtin_expect (tp->tm_year > INT_MAX - 1900, 0))
|
if (__builtin_expect (tp->tm_year > INT_MAX - 1900, 0))
|
||||||
{
|
{
|
||||||
|
eoverflow:
|
||||||
__set_errno (EOVERFLOW);
|
__set_errno (EOVERFLOW);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sprintf (buf, format,
|
int n = snprintf (buf, buflen, format,
|
||||||
(tp->tm_wday < 0 || tp->tm_wday >= 7 ?
|
(tp->tm_wday < 0 || tp->tm_wday >= 7 ?
|
||||||
"???" : ab_day_name (tp->tm_wday)),
|
"???" : ab_day_name (tp->tm_wday)),
|
||||||
(tp->tm_mon < 0 || tp->tm_mon >= 12 ?
|
(tp->tm_mon < 0 || tp->tm_mon >= 12 ?
|
||||||
"???" : ab_month_name (tp->tm_mon)),
|
"???" : ab_month_name (tp->tm_mon)),
|
||||||
tp->tm_mday, tp->tm_hour, tp->tm_min,
|
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;
|
return NULL;
|
||||||
|
if (n >= buflen)
|
||||||
|
goto eoverflow;
|
||||||
|
|
||||||
return buf;
|
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)
|
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;
|
result = 1;
|
||||||
}
|
}
|
||||||
char buf[1000];
|
char buf[1000];
|
||||||
|
errno = 0;
|
||||||
s = asctime_r (tp, buf);
|
s = asctime_r (tp, buf);
|
||||||
if (s != NULL || errno != EOVERFLOW)
|
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