public inbox for libc-hacker@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Fix mktime
@ 2004-12-02 18:30 Jakub Jelinek
  2004-12-02 22:18 ` Roland McGrath
  0 siblings, 1 reply; 7+ messages in thread
From: Jakub Jelinek @ 2004-12-02 18:30 UTC (permalink / raw)
  To: Ulrich Drepper, Roland McGrath, Paul Eggert; +Cc: Glibc hackers

Hi!

The latest changes in mktime apparently broke mktime when
tm_sec is < 0 or >= 60.  mktime returns as if the tm_sec given
was 0 resp. 59.

2004-12-01  Jakub Jelinek  <jakub@redhat.com>

	* time/mktime.c (__mktime_internal): If sec_requested != sec,
	convert t2, not t.
	* time/Makefile (tests): Add tst-mktime3.
	* time/tst-mktime3.c: New test.

--- libc/time/Makefile.jj	2004-11-01 13:25:55.000000000 +0100
+++ libc/time/Makefile	2004-12-02 19:03:43.945786121 +0100
@@ -34,7 +34,8 @@ aux :=	    era alt_digit lc-time-cleanup
 distribute := datemsk
 
 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
 
 include ../Rules
 
--- libc/time/mktime.c.jj	2004-11-12 13:58:25.000000000 +0100
+++ libc/time/mktime.c	2004-12-02 19:24:16.362448335 +0100
@@ -463,8 +463,9 @@ __mktime_internal (struct tm *tp,
       t2 = t1 + sec_adjustment;
       if (((t1 < t) != (sec_requested < 0))
 	  | ((t2 < t1) != (sec_adjustment < 0))
-	  | ! (*convert) (&t, &tm))
+	  | ! (*convert) (&t2, &tm))
 	return -1;
+      t = t2;
     }
 
   *tp = tm;
--- libc/time/tst-mktime3.c.jj	2004-12-02 19:00:40.590492064 +0100
+++ libc/time/tst-mktime3.c	2004-12-02 19:15:16.564452958 +0100
@@ -0,0 +1,48 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+
+struct tm tests[] =
+{
+  { .tm_sec = -1, .tm_mday = 1, .tm_year = 104 },
+  { .tm_sec = 65, .tm_min = 59, .tm_hour = 23, .tm_mday = 31,
+    .tm_mon = 11, .tm_year = 101 }
+};
+struct tm expected[] =
+{
+  { .tm_sec = 59, .tm_min = 59, .tm_hour = 23, .tm_mday = 31,
+    .tm_mon = 11, .tm_year = 103, .tm_wday = 3, .tm_yday = 364 },
+  { .tm_sec = 5, .tm_mday = 1, .tm_year = 102, .tm_wday = 2 }
+};
+
+int
+main (void)
+{
+  setenv ("TZ", "UTC", 1);
+  int i;
+  for (i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i)
+    {
+      if (mktime (&tests[i]) < 0)
+	{
+	  printf ("mktime %d failed\n", i);
+	  return 1;
+	}
+#define CHECK(name) \
+      if (tests[i].name != expected[i].name)			\
+	{							\
+	  printf ("test %d " #name " got %d expected %d\n",	\
+		  i, tests[i].name, expected[i].name);		\
+	  return 1;						\
+	}
+      CHECK (tm_sec)
+      CHECK (tm_min)
+      CHECK (tm_hour)
+      CHECK (tm_mday)
+      CHECK (tm_mon)
+      CHECK (tm_year)
+      CHECK (tm_wday)
+      CHECK (tm_yday)
+      CHECK (tm_isdst)
+    }
+  return 0;
+}

	Jakub

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix mktime
  2004-12-02 18:30 [PATCH] Fix mktime Jakub Jelinek
@ 2004-12-02 22:18 ` Roland McGrath
  0 siblings, 0 replies; 7+ messages in thread
From: Roland McGrath @ 2004-12-02 22:18 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Ulrich Drepper, Paul Eggert, Glibc hackers

> 2004-12-01  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* time/mktime.c (__mktime_internal): If sec_requested != sec,
> 	convert t2, not t.
> 	* time/Makefile (tests): Add tst-mktime3.
> 	* time/tst-mktime3.c: New test.

Applied.


Thanks,
Roland

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix mktime
  2002-04-13  2:59 Jakub Jelinek
  2002-04-14 23:27 ` Ulrich Drepper
@ 2002-04-17  5:22 ` Thorsten Kukuk
  1 sibling, 0 replies; 7+ messages in thread
From: Thorsten Kukuk @ 2002-04-17  5:22 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Glibc hackers

On Sat, Apr 13, Jakub Jelinek wrote:

> Hi!
> 
> The PR libc/2738 fix was not entirely correct, since even tm with tm_year 69
> is representable in certain timezones. This caused e.g. perl-Date-Calc tests
> to fail. Below is a fix. Years before 69 surely cannot be represented, for
> 69 it computes the year and checks for overflow afterwards.
> 
> 2002-04-13  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* time/mktime.c (__mktime_internal): If year is 69, don't bail out
> 	early, but check whether it overflowed afterwards.
> 	* time/tst-mktime.c (main): Add new tests.

make check does not longer pass for me with this. Output of
tst-mktime.out is:

Wednesday
Dec 31 1969 EST test passed
mktime returned 3749, expected -1

  Thorsten

-- 
Thorsten Kukuk       http://www.suse.de/~kukuk/        kukuk@suse.de
SuSE Linux AG        Deutschherrenstr. 15-19       D-90429 Nuernberg
--------------------------------------------------------------------    
Key fingerprint = A368 676B 5E1B 3E46 CFCE  2D97 F8FD 4E23 56C6 FB4B

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix mktime
  2002-04-13  2:59 Jakub Jelinek
@ 2002-04-14 23:27 ` Ulrich Drepper
  2002-04-17  5:22 ` Thorsten Kukuk
  1 sibling, 0 replies; 7+ messages in thread
From: Ulrich Drepper @ 2002-04-14 23:27 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Glibc hackers

[-- Attachment #1: Type: text/plain, Size: 541 bytes --]

On Sat, 2002-04-13 at 02:59, Jakub Jelinek wrote:

> 2002-04-13  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* time/mktime.c (__mktime_internal): If year is 69, don't bail out
> 	early, but check whether it overflowed afterwards.
> 	* time/tst-mktime.c (main): Add new tests.

I've applied the patch.  Thanks,

-- 
---------------.                          ,-.   1325 Chesapeake Terrace
Ulrich Drepper  \    ,-------------------'   \  Sunnyvale, CA 94089 USA
Red Hat          `--' drepper at redhat.com   `------------------------

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 232 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] Fix mktime
@ 2002-04-13  2:59 Jakub Jelinek
  2002-04-14 23:27 ` Ulrich Drepper
  2002-04-17  5:22 ` Thorsten Kukuk
  0 siblings, 2 replies; 7+ messages in thread
From: Jakub Jelinek @ 2002-04-13  2:59 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: Glibc hackers

Hi!

The PR libc/2738 fix was not entirely correct, since even tm with tm_year 69
is representable in certain timezones. This caused e.g. perl-Date-Calc tests
to fail. Below is a fix. Years before 69 surely cannot be represented, for
69 it computes the year and checks for overflow afterwards.

2002-04-13  Jakub Jelinek  <jakub@redhat.com>

	* time/mktime.c (__mktime_internal): If year is 69, don't bail out
	early, but check whether it overflowed afterwards.
	* time/tst-mktime.c (main): Add new tests.

--- libc/time/mktime.c.jj	Sun Apr  7 17:52:27 2002
+++ libc/time/mktime.c	Sat Apr 13 11:12:05 2002
@@ -259,8 +259,10 @@ __mktime_internal (struct tm *tp,
 
   int sec_requested = sec;
 
-  /* Only years after 1970 are defined.  */
-  if (year < 70)
+  /* Only years after 1970 are defined.
+     If year is 69, it might still be representable due to
+     timezone differnces.  */
+  if (year < 69)
     return -1;
 
 #if LEAP_SECONDS_POSSIBLE
@@ -370,6 +372,14 @@ __mktime_internal (struct tm *tp,
 	return -1;
     }
 
+  if (year == 69)
+    {
+      /* If year was 69, need to check whether the time was representable
+	 or not.  */
+      if (t < 0 || t > 2 * 24 * 60 * 60)
+	return -1;
+    }
+
   *tp = tm;
   return t;
 }
--- libc/time/tst-mktime.c.jj	Sat Apr 13 11:45:06 2002
+++ libc/time/tst-mktime.c	Sat Apr 13 11:58:22 2002
@@ -5,7 +5,8 @@
 int
 main (void)
 {
-  struct tm time_str;
+  struct tm time_str, *tm;
+  time_t t;
   char daybuf[20];
   int result;
 
@@ -29,5 +30,38 @@ main (void)
       result = strcmp (daybuf, "Wednesday") != 0;
     }
 
+  setenv ("TZ", "EST", 1);
+#define EVENING69 1 * 60 * 60 + 2 * 60 + 29
+  t = EVENING69;
+  tm = localtime (&t);
+  if (tm == NULL)
+    {
+      (void) puts ("localtime returned NULL");
+      result = 1;
+    }
+  else
+    {
+      time_str = *tm;
+      t = mktime (&time_str);
+      if (t != EVENING69)
+        {
+          printf ("mktime returned %ld, expected %ld\n",
+		  (long) t, EVENING69);
+	  result = 1;
+        }
+      else
+        (void) puts ("Dec 31 1969 EST test passed");
+
+      setenv ("TZ", "CET", 1);
+      t = mktime (&time_str);
+      if (t != (time_t) -1)
+        {
+	  printf ("mktime returned %ld, expected -1\n", (long) t);
+	  result = 1;
+        }
+      else
+        (void) puts ("Dec 31 1969 CET test passed");
+    }
+
   return result;
 }

	Jakub

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix mktime
  2002-04-05  4:36 Jakub Jelinek
@ 2002-04-05  8:45 ` Ulrich Drepper
  0 siblings, 0 replies; 7+ messages in thread
From: Ulrich Drepper @ 2002-04-05  8:45 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Glibc hackers

[-- Attachment #1: Type: text/plain, Size: 471 bytes --]

On Fri, 2002-04-05 at 04:36, Jakub Jelinek wrote:

> 2002-04-05  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* time/mktime.c (__mktime_internal): Move check for year < 70 below
> 	all variable declarations.

I've applied the patch.  Thanks,

-- 
---------------.                          ,-.   1325 Chesapeake Terrace
Ulrich Drepper  \    ,-------------------'   \  Sunnyvale, CA 94089 USA
Red Hat          `--' drepper at redhat.com   `------------------------

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 232 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] Fix mktime
@ 2002-04-05  4:36 Jakub Jelinek
  2002-04-05  8:45 ` Ulrich Drepper
  0 siblings, 1 reply; 7+ messages in thread
From: Jakub Jelinek @ 2002-04-05  4:36 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: Glibc hackers

Hi!

ISO C99ism which older GCCs (< 3.0, or < 3.1?) don't cope with:

2002-04-05  Jakub Jelinek  <jakub@redhat.com>

	* time/mktime.c (__mktime_internal): Move check for year < 70 below
	all variable declarations.

--- libc/time/mktime.c.jj	Fri Apr  5 14:34:22 2002
+++ libc/time/mktime.c	Fri Apr  5 14:36:38 2002
@@ -246,10 +246,6 @@ __mktime_internal (struct tm *tp,
   int mon_years = mon / 12 - negative_mon_remainder;
   int year = year_requested + mon_years;
 
-  /* Only years after 1970 are defined.  */
-  if (year < 70)
-    return -1;
-
    /* The other values need not be in range:
      the remaining code handles minor overflows correctly,
      assuming int and time_t arithmetic wraps around.
@@ -271,6 +267,10 @@ __mktime_internal (struct tm *tp,
     sec = 59;
 #endif
 
+  /* Only years after 1970 are defined.  */
+  if (year < 70)
+    return -1;
+
   /* Invert CONVERT by probing.  First assume the same offset as last time.
      Then repeatedly use the error to improve the guess.  */
 

	Jakub

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2004-12-02 22:18 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-12-02 18:30 [PATCH] Fix mktime Jakub Jelinek
2004-12-02 22:18 ` Roland McGrath
  -- strict thread matches above, loose matches on Subject: below --
2002-04-13  2:59 Jakub Jelinek
2002-04-14 23:27 ` Ulrich Drepper
2002-04-17  5:22 ` Thorsten Kukuk
2002-04-05  4:36 Jakub Jelinek
2002-04-05  8:45 ` Ulrich Drepper

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).