diff options
author | Ulrich Drepper <drepper@redhat.com> | 2005-10-14 15:17:40 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2005-10-14 15:17:40 +0000 |
commit | ce982312e888ff1fd9b869240951805d281f7517 (patch) | |
tree | e68f0f42b945ce719ad1ea032b59deb1bc78e57b /time/asctime.c | |
parent | 576c8451485408d776914e756e5cc554e9d93eda (diff) | |
download | glibc-ce982312e888ff1fd9b869240951805d281f7517.tar glibc-ce982312e888ff1fd9b869240951805d281f7517.tar.gz glibc-ce982312e888ff1fd9b869240951805d281f7517.tar.bz2 glibc-ce982312e888ff1fd9b869240951805d281f7517.zip |
[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.
Diffstat (limited to 'time/asctime.c')
-rw-r--r-- | time/asctime.c | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/time/asctime.c b/time/asctime.c index 8ac4aa76a4..db29dffb2f 100644 --- a/time/asctime.c +++ b/time/asctime.c @@ -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, - (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) |