diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | time/Makefile | 5 | ||||
-rw-r--r-- | time/strptime_l.c | 11 | ||||
-rw-r--r-- | time/tst-strptime3.c | 55 |
4 files changed, 77 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog index 8eaab91827..070da56092 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2007-02-08 Jakub Jelinek <jakub@redhat.com> + + [BZ #3944] + * time/strptime_l.c (__strptime_internal): Set have_mon for + %b/%B/%h. Set have_mon and have_mday if tm_mon and tm_mday + have been computed from tm_yday and tm_year. Don't crash + in day_of_the_week or day_of_the_year if not have_mon + and tm_mon contains bogus value. + * time/Makefile (tests): Add tst-strptime3. + * time/tst-strptime3.c: New test. + 2007-02-05 Jakub Jelinek <jakub@redhat.com> [BZ #3957] diff --git a/time/Makefile b/time/Makefile index d93b84bb2f..8ce34e4565 100644 --- a/time/Makefile +++ b/time/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991-2003, 2004, 2005 Free Software Foundation, Inc. +# Copyright (C) 1991-2003, 2004, 2005, 2007 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -35,7 +35,8 @@ 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 bug-asctime_r bug-mktime1 + tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \ + tst-strptime3 include ../Rules diff --git a/time/strptime_l.c b/time/strptime_l.c index dc0cc686fd..443a6fa88e 100644 --- a/time/strptime_l.c +++ b/time/strptime_l.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2004, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -400,6 +400,7 @@ __strptime_internal (rp, fmt, tm, decided, era_cnt LOCALE_PARAM) /* Does not match a month name. */ return NULL; tm->tm_mon = cnt; + have_mon = 1; want_xday = 1; break; case 'c': @@ -1085,11 +1086,15 @@ __strptime_internal (rp, fmt, tm, decided, era_cnt LOCALE_PARAM) tm->tm_mday = (tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); + have_mon = 1; + have_mday = 1; } - day_of_the_week (tm); + /* Don't crash in day_of_the_week if tm_mon is uninitialized. */ + if (have_mon || (unsigned) tm->tm_mon <= 11) + day_of_the_week (tm); } - if (want_xday && !have_yday) + if (want_xday && !have_yday && (have_mon || (unsigned) tm->tm_mon <= 11)) day_of_the_year (tm); if ((have_uweek || have_wweek) && have_wday) diff --git a/time/tst-strptime3.c b/time/tst-strptime3.c new file mode 100644 index 0000000000..9a8c6485e7 --- /dev/null +++ b/time/tst-strptime3.c @@ -0,0 +1,55 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + + +int +main (void) +{ + int result = 0; + struct tm tm; + + memset (&tm, 0xaa, sizeof (tm)); + + /* Test we don't crash on uninitialized struct tm. + Some fields might contain bogus values until everything + needed is initialized, but we shouldn't crash. */ + if (strptime ("2007", "%Y", &tm) == NULL + || strptime ("12", "%d", &tm) == NULL + || strptime ("Feb", "%b", &tm) == NULL + || strptime ("13", "%M", &tm) == NULL + || strptime ("21", "%S", &tm) == NULL + || strptime ("16", "%H", &tm) == NULL) + { + puts ("strptimes failed"); + result = 1; + } + + if (tm.tm_sec != 21 || tm.tm_min != 13 || tm.tm_hour != 16 + || tm.tm_mday != 12 || tm.tm_mon != 1 || tm.tm_year != 107 + || tm.tm_wday != 1 || tm.tm_yday != 42) + { + puts ("unexpected tm content"); + result = 1; + } + + if (strptime ("8", "%d", &tm) == NULL) + { + puts ("strptime failed"); + result = 1; + } + + if (tm.tm_sec != 21 || tm.tm_min != 13 || tm.tm_hour != 16 + || tm.tm_mday != 8 || tm.tm_mon != 1 || tm.tm_year != 107 + || tm.tm_wday != 4 || tm.tm_yday != 38) + { + puts ("unexpected tm content"); + result = 1; + } + + if (result == 0) + puts ("all OK"); + + return 0; +} |