Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[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.
  • Loading branch information
Ulrich Drepper committed Oct 14, 2005
1 parent 576c845 commit ce98231
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 18 deletions.
9 changes: 9 additions & 0 deletions ChangeLog
@@ -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.
Expand Down
2 changes: 1 addition & 1 deletion time/Makefile
Expand Up @@ -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

Expand Down
49 changes: 32 additions & 17 deletions time/asctime.c
Expand Up @@ -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)
{
Expand All @@ -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,
(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)
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);
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)
1 change: 1 addition & 0 deletions time/bug-asctime.c
Expand Up @@ -19,6 +19,7 @@ do_test (void)
result = 1;
}
char buf[1000];
errno = 0;
s = asctime_r (tp, buf);
if (s != NULL || errno != EOVERFLOW)
{
Expand Down
26 changes: 26 additions & 0 deletions time/bug-asctime_r.c
@@ -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"

0 comments on commit ce98231

Please sign in to comment.