posixtm: don't reject a time with "60" as the number of seconds
authorJim Meyering <meyering@redhat.com>
Sat, 12 Sep 2009 22:35:49 +0000 (00:35 +0200)
committerJim Meyering <meyering@redhat.com>
Mon, 14 Sep 2009 11:20:59 +0000 (13:20 +0200)
* lib/posixtm.c (posixtime): The code to reject invalid dates would
also reject a time specified with the .60 suffix, whereas POSIX allows
that, in order to accommodate leap seconds.  Don't reject that.
(main): Adjust tests accordingly.
* modules/posixtm (Depends-on): Add stpcpy.

ChangeLog
lib/posixtm.c
modules/posixtm

index 94bac83..dc32b4d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2009-09-13  Jim Meyering  <meyering@redhat.com>
+
+       posixtm: don't reject a time that specify "60" as the number of seconds
+       * lib/posixtm.c (posixtime): The code to reject invalid dates
+       would also reject a time specified with the .60 suffix.
+       But POSIX allows that, in order to accommodate leap seconds.
+       So don't reject it.
+       (main): Adjust tests accordingly.
+       * modules/posixtm (Depends-on): Add stpcpy.
+
 2009-09-11  Jim Meyering  <meyering@redhat.com>
 
        announce-gen: include [$release_type] in emitted Subject:
index 4d044a3..0a1e779 100644 (file)
@@ -1,7 +1,7 @@
 /* Parse dates for touch and date.
 
    Copyright (C) 1989, 1990, 1991, 1998, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007 Free Software Foundation Inc.
+   2005, 2006, 2007, 2009 Free Software Foundation Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -207,14 +207,29 @@ posixtime (time_t *p, const char *s, unsigned int syntax_bits)
        return false;
     }
 
-  /* Reject dates like "September 31" and times like "25:61".  */
+  /* Reject dates like "September 31" and times like "25:61".
+     Do not reject times that specify "60" as the number of seconds.  */
   if ((tm0.tm_year ^ tm->tm_year)
       | (tm0.tm_mon ^ tm->tm_mon)
       | (tm0.tm_mday ^ tm->tm_mday)
       | (tm0.tm_hour ^ tm->tm_hour)
       | (tm0.tm_min ^ tm->tm_min)
       | (tm0.tm_sec ^ tm->tm_sec))
-    return false;
+    {
+      /* Any mismatch without 60 in the tm_sec field is invalid.  */
+      if (tm0.tm_sec != 60)
+        return false;
+
+      {
+        /* Allow times like 01:35:60 or 23:59:60.  */
+        time_t dummy;
+        char buf[16];
+        char *b = stpcpy (buf, s);
+        strcpy (b - 2, "59");
+        if (!posixtime (&dummy, buf, syntax_bits))
+          return false;
+      }
+    }
 
   *p = t;
   return true;
@@ -251,13 +266,13 @@ BEGIN-DATA
 197001010000.00 13            0 Thu Jan  1 00:00:00 1970
 197001010000.01 13            1 Thu Jan  1 00:00:01 1970
 197001010001.00 13           60 Thu Jan  1 00:01:00 1970
+197001010000.60 13           60 Thu Jan  1 00:01:00 1970
 197001010100.00 13         3600 Thu Jan  1 01:00:00 1970
 197001020000.00 13        86400 Fri Jan  2 00:00:00 1970
 197002010000.00 13      2678400 Sun Feb  1 00:00:00 1970
 197101010000.00 13     31536000 Fri Jan  1 00:00:00 1971
 197001000000.00 13            * *
 197000010000.00 13            * *
-197001010000.60 13            * *
 197001010060.00 13            * *
 197001012400.00 13            * *
 197001320000.00 13            * *
index 06af4c8..425c175 100644 (file)
@@ -9,6 +9,7 @@ m4/posixtm.m4
 Depends-on:
 mktime
 stdbool
+stpcpy
 
 configure.ac:
 gl_POSIXTM