From: Paul Eggert Date: Sun, 3 Aug 2014 15:38:52 +0000 (-0700) Subject: Don't mishandle year-9999 dates. X-Git-Tag: emacs-25.0.90~2635^2~679^2~534 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=308cc448e5d6ffd44c7ff366a99d34bbfb0e8c4d;p=emacs.git Don't mishandle year-9999 dates. * 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 --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 8c7ac9c7423..28fa5d1a5e6 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,11 @@ +2014-08-03 Paul Eggert + + 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 * progmodes/python.el: Completion code cleanups. diff --git a/lisp/calendar/parse-time.el b/lisp/calendar/parse-time.el index 6bfccec94c6..6c88210030b 100644 --- a/lisp/calendar/parse-time.el +++ b/lisp/calendar/parse-time.el @@ -131,7 +131,7 @@ `(((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) diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el index b04cfcd9fe4..48fe2294354 100644 --- a/lisp/calendar/time-date.el +++ b/lisp/calendar/time-date.el @@ -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 diff --git a/lisp/url/ChangeLog b/lisp/url/ChangeLog index b8e34ea65c4..92945b37951 100644 --- a/lisp/url/ChangeLog +++ b/lisp/url/ChangeLog @@ -1,3 +1,9 @@ +2014-08-03 Paul Eggert + + 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 * url-http.el (url-http-end-of-headers): Remove duplicate defvar. diff --git a/lisp/url/url-cookie.el b/lisp/url/url-cookie.el index 55e0fb33951..f89886b95dd 100644 --- a/lisp/url/url-cookie.el +++ b/lisp/url/url-cookie.el @@ -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." diff --git a/src/ChangeLog b/src/ChangeLog index dce13035766..b0768dd5489 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,14 @@ 2014-08-03 Paul Eggert + 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): diff --git a/src/editfns.c b/src/editfns.c index e8d4478f2f6..f779bb9ebb6 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -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; } } diff --git a/src/keyboard.c b/src/keyboard.c index 81b68ab343c..5c7ad95f5ac 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -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)); }