aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2019-01-01 11:33:10 -0800
committerPaul Eggert2019-01-01 11:33:37 -0800
commit227343947f083e1094ebd3770f774b480beb2590 (patch)
tree54c05f6690abbe94c80426c36ebe64231b275da7 /src
parent355b1c3cb91a226d1f58098944542142eddccb60 (diff)
downloademacs-227343947f083e1094ebd3770f774b480beb2590.tar.gz
emacs-227343947f083e1094ebd3770f774b480beb2590.zip
decode-time: allow bignum years
* src/timefns.c (TM_YEAR_BASE): Now a constant as it need not be a macro. (Fdecode_time): Do not signal an overflow merely because the Gregorian year number does not fix in a fixnum (which can happen on hosts with 64-bit time_t and with 32-bit int and EMACS_INT).
Diffstat (limited to 'src')
-rw-r--r--src/timefns.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/src/timefns.c b/src/timefns.c
index 437b5b22131..4c99fe58061 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -44,7 +44,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
44# define HAVE_TZALLOC_BUG false 44# define HAVE_TZALLOC_BUG false
45#endif 45#endif
46 46
47#define TM_YEAR_BASE 1900 47enum { TM_YEAR_BASE = 1900 };
48 48
49#ifndef HAVE_TM_GMTOFF 49#ifndef HAVE_TM_GMTOFF
50# define HAVE_TM_GMTOFF false 50# define HAVE_TM_GMTOFF false
@@ -1336,12 +1336,22 @@ usage: (decode-time &optional TIME ZONE) */)
1336 1336
1337 if (!tm) 1337 if (!tm)
1338 time_error (localtime_errno); 1338 time_error (localtime_errno);
1339 if (! (MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= local_tm.tm_year
1340 && local_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE))
1341 time_overflow ();
1342 1339
1343 /* Avoid overflow when INT_MAX < EMACS_INT_MAX. */ 1340 Lisp_Object year;
1344 EMACS_INT tm_year_base = TM_YEAR_BASE; 1341 if (FASTER_TIMEFNS
1342 && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= local_tm.tm_year
1343 && local_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE)
1344 {
1345 /* Avoid overflow when INT_MAX - TM_YEAR_BASE < local_tm.tm_year. */
1346 EMACS_INT tm_year_base = TM_YEAR_BASE;
1347 year = make_fixnum (local_tm.tm_year + tm_year_base);
1348 }
1349 else
1350 {
1351 mpz_set_si (mpz[0], local_tm.tm_year);
1352 mpz_add_ui (mpz[0], mpz[0], TM_YEAR_BASE);
1353 year = make_integer_mpz ();
1354 }
1345 1355
1346 return CALLN (Flist, 1356 return CALLN (Flist,
1347 make_fixnum (local_tm.tm_sec), 1357 make_fixnum (local_tm.tm_sec),
@@ -1349,7 +1359,7 @@ usage: (decode-time &optional TIME ZONE) */)
1349 make_fixnum (local_tm.tm_hour), 1359 make_fixnum (local_tm.tm_hour),
1350 make_fixnum (local_tm.tm_mday), 1360 make_fixnum (local_tm.tm_mday),
1351 make_fixnum (local_tm.tm_mon + 1), 1361 make_fixnum (local_tm.tm_mon + 1),
1352 make_fixnum (local_tm.tm_year + tm_year_base), 1362 year,
1353 make_fixnum (local_tm.tm_wday), 1363 make_fixnum (local_tm.tm_wday),
1354 (local_tm.tm_isdst < 0 ? make_fixnum (-1) 1364 (local_tm.tm_isdst < 0 ? make_fixnum (-1)
1355 : local_tm.tm_isdst == 0 ? Qnil : Qt), 1365 : local_tm.tm_isdst == 0 ? Qnil : Qt),
@@ -1360,7 +1370,7 @@ usage: (decode-time &optional TIME ZONE) */)
1360 : Qnil)); 1370 : Qnil));
1361} 1371}
1362 1372
1363/* Return OBJ - OFFSET, checking that OBJ is a valid fixnum and that 1373/* Return OBJ - OFFSET, checking that OBJ is a valid integer and that
1364 the result is representable as an int. 0 <= OFFSET <= TM_YEAR_BASE. */ 1374 the result is representable as an int. 0 <= OFFSET <= TM_YEAR_BASE. */
1365static int 1375static int
1366check_tm_member (Lisp_Object obj, int offset) 1376check_tm_member (Lisp_Object obj, int offset)