]> git.eshelyaron.com Git - emacs.git/commitdiff
Don't mishandle year-9999 dates.
authorPaul Eggert <eggert@cs.ucla.edu>
Sun, 3 Aug 2014 15:38:52 +0000 (08:38 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 3 Aug 2014 15:38:52 +0000 (08:38 -0700)
* lisp/calendar/parse-time.el (parse-time-rules):
Allow years up to most-positive-fixnum.
* lisp/calendar/time-date.el (date-to-time):
Pass "Specified time is not representable" errors through.
* lisp/url/url-cookie.el (url-cookie-expired-p): Treat out-of-range
expiration dates as if they were far in the future.
* src/editfns.c (decode_time_components): Store an invalid timespec
on overflow, instead of returning false, so that the caller can
distinguish overflow from other errors.
(lisp_time_argument, lisp_seconds_argument): If the time is out
of range, signal a time overflow instead of an invalid time spec.
* src/keyboard.c (decode_timer): Treat time overflow like other
timespec errors.

Fixes: debbugs:18176
lisp/ChangeLog
lisp/calendar/parse-time.el
lisp/calendar/time-date.el
lisp/url/ChangeLog
lisp/url/url-cookie.el
src/ChangeLog
src/editfns.c
src/keyboard.c

index 8c7ac9c74234f3c0ff843f3bceef9394a7c8e52c..28fa5d1a5e6e3bb01508e4b5f26511562e77a0f5 100644 (file)
@@ -1,3 +1,11 @@
+2014-08-03  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Don't mishandle year-9999 dates (Bug#18176).
+       * calendar/parse-time.el (parse-time-rules):
+       Allow years up to most-positive-fixnum.
+       * calendar/time-date.el (date-to-time):
+       Pass "Specified time is not representable" errors through.
+
 2014-08-02  Fabián Ezequiel Gallina  <fgallina@gnu.org>
 
        * progmodes/python.el: Completion code cleanups.
index 6bfccec94c69947e760baa67c66fcec50780587e..6c88210030b0e8ffb12830253d14dad3f60a9d87 100644 (file)
   `(((6) parse-time-weekdays)
     ((3) (1 31))
     ((4) parse-time-months)
-    ((5) (100 4038))
+    ((5) (100 ,most-positive-fixnum))
     ((2 1 0)
      ,#'(lambda () (and (stringp parse-time-elt)
                        (= (length parse-time-elt) 8)
index b04cfcd9fe41ac21d9619d1e0861d6ee0bfecb76..48fe2294354a1468be3f085641cc67ff5b3e60f3 100644 (file)
@@ -119,13 +119,20 @@ it is assumed that PICO was omitted and should be treated as zero."
 (defun date-to-time (date)
   "Parse a string DATE that represents a date-time and return a time value.
 If DATE lacks timezone information, GMT is assumed."
-  (condition-case ()
+  (condition-case err
       (apply 'encode-time (parse-time-string date))
-    (error (condition-case ()
-              (apply 'encode-time
-                     (parse-time-string
-                      (timezone-make-date-arpa-standard date)))
-            (error (error "Invalid date: %s" date))))))
+    (error
+     (let ((overflow-error '(error "Specified time is not representable")))
+       (if (equal err overflow-error)
+          (apply 'signal err)
+        (condition-case err
+            (apply 'encode-time
+                   (parse-time-string
+                    (timezone-make-date-arpa-standard date)))
+          (error
+           (if (equal err overflow-error)
+               (apply 'signal err)
+             (error "Invalid date: %s" date)))))))))
 
 ;; Bit of a mess.  Emacs has float-time since at least 21.1.
 ;; This file is synced to Gnus, and XEmacs packages may have been written
index b8e34ea65c4e52e6a38868c4e195e00bfd4a0460..92945b37951d5fdb5374a0487afae88c5509dc71 100644 (file)
@@ -1,3 +1,9 @@
+2014-08-03  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Don't mishandle dates in the year 9999 (Bug#18176).
+       * url-cookie.el (url-cookie-expired-p): Treat out-of-range
+       expiration dates as if they were far in the future.
+
 2014-06-26  Leo Liu  <sdl.web@gmail.com>
 
        * url-http.el (url-http-end-of-headers): Remove duplicate defvar.
index 55e0fb33951da94d5a607b373d98a12a1d2a0874..f89886b95dd4a50da775497881cbfff5161ede2b 100644 (file)
@@ -158,7 +158,9 @@ telling Microsoft that."
   "Return non-nil if COOKIE is expired."
   (let ((exp (url-cookie-expires cookie)))
     (and (> (length exp) 0)
-        (> (float-time) (float-time (date-to-time exp))))))
+        (condition-case ()
+            (> (float-time) (float-time (date-to-time exp)))
+          (error nil)))))
 
 (defun url-cookie-retrieve (host &optional localpart secure)
   "Retrieve all cookies for a specified HOST and LOCALPART."
index dce13035766a9a1ac092df5d68f6bcd792eedf7d..b0768dd5489e6de3699278cb35c618901a0e7997 100644 (file)
@@ -1,5 +1,14 @@
 2014-08-03  Paul Eggert  <eggert@cs.ucla.edu>
 
+       Don't mishandle year-9999 dates (Bug#18176).
+       * editfns.c (decode_time_components): Store an invalid timespec
+       on overflow, instead of returning false, so that the caller can
+       distinguish overflow from other errors.
+       (lisp_time_argument, lisp_seconds_argument): If the time is out
+       of range, signal a time overflow instead of an invalid time spec.
+       * keyboard.c (decode_timer): Treat time overflow like other
+       timespec errors.
+
        Avoid undefined behavior with signed left shift.
        Caught by 'gcc -fsanitize=undefined'.
        * dispextern.h, scroll.c (scrolling_max_lines_saved, scrolling_1):
index e8d4478f2f66475f59f99452090de327f4979df0..f779bb9ebb6b447557b5073dba6d7dd5f144b1d9 100644 (file)
@@ -1516,7 +1516,8 @@ disassemble_lisp_time (Lisp_Object specified_time, Lisp_Object *phigh,
    list, generate the corresponding time value.
 
    If RESULT is not null, store into *RESULT the converted time;
-   this can fail if the converted time does not fit into struct timespec.
+   if the converted time does not fit into struct timespec,
+   store an invalid timespec to indicate the overflow.
    If *DRESULT is not null, store into *DRESULT the number of
    seconds since the start of the POSIX Epoch.
 
@@ -1529,7 +1530,7 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
   EMACS_INT hi, lo, us, ps;
   if (! (INTEGERP (high) && INTEGERP (low)
         && INTEGERP (usec) && INTEGERP (psec)))
-    return 0;
+    return false;
   hi = XINT (high);
   lo = XINT (low);
   us = XINT (usec);
@@ -1555,16 +1556,13 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
          *result = make_timespec ((sec << 16) + lo, us * 1000 + ps / 1000);
        }
       else
-       {
-         /* Overflow in the highest-order component.  */
-         return 0;
-       }
+       *result = invalid_timespec ();
     }
 
   if (dresult)
     *dresult = (us * 1e6 + ps) / 1e12 + lo + hi * 65536.0;
 
-  return 1;
+  return true;
 }
 
 /* Decode a Lisp list SPECIFIED_TIME that represents a time.
@@ -1576,22 +1574,23 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
 struct timespec
 lisp_time_argument (Lisp_Object specified_time)
 {
-  struct timespec t;
   if (NILP (specified_time))
-    t = current_timespec ();
+    return current_timespec ();
   else
     {
       Lisp_Object high, low, usec, psec;
+      struct timespec t;
       if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec)
             && decode_time_components (high, low, usec, psec, &t, 0)))
        error ("Invalid time specification");
+      if (! timespec_valid_p (t))
+       time_overflow ();
+      return t;
     }
-  return t;
 }
 
 /* Like lisp_time_argument, except decode only the seconds part,
-   do not allow out-of-range time stamps, do not check the subseconds part,
-   and always round down.  */
+   and do not check the subseconds part.  */
 static time_t
 lisp_seconds_argument (Lisp_Object specified_time)
 {
@@ -1605,6 +1604,8 @@ lisp_seconds_argument (Lisp_Object specified_time)
             && decode_time_components (high, low, make_number (0),
                                        make_number (0), &t, 0)))
        error ("Invalid time specification");
+      if (! timespec_valid_p (t))
+       time_overflow ();
       return t.tv_sec;
     }
 }
index 81b68ab343c8766000592d7f8fe9f36ee474d558..5c7ad95f5ac692ca0472ddfe86b758af3adbbe15 100644 (file)
@@ -4370,8 +4370,9 @@ decode_timer (Lisp_Object timer, struct timespec *result)
   if (! NILP (vector[0]))
     return 0;
 
-  return decode_time_components (vector[1], vector[2], vector[3], vector[8],
-                                result, 0);
+  return (decode_time_components (vector[1], vector[2], vector[3], vector[8],
+                                 result, 0)
+         && timespec_valid_p (*result));
 }