diff options
| author | Paul Eggert | 2018-09-04 19:14:01 -0700 |
|---|---|---|
| committer | Paul Eggert | 2018-09-04 19:15:57 -0700 |
| commit | ccb3891ff5446b578b9306aec0fd9c5ec3ed8e98 (patch) | |
| tree | 888bda0e0584ef78d2a3b25cc6c03b35b6b8ea8e /src | |
| parent | ecb985c10d5241a65ab9552ebfcecaa150b35427 (diff) | |
| download | emacs-ccb3891ff5446b578b9306aec0fd9c5ec3ed8e98.tar.gz emacs-ccb3891ff5446b578b9306aec0fd9c5ec3ed8e98.zip | |
Fix format-time-string bignum bug
The problem can occur on 32-bit platforms with current timestamps.
* src/editfns.c (disassemble_lisp_time, decode_time_components):
Support seconds counts that are bignums.
* test/src/editfns-tests.el (editfns-tests--have-leap-seconds):
New function.
(format-time-string-with-bignum-on-32-bit): New test.
Diffstat (limited to 'src')
| -rw-r--r-- | src/editfns.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/src/editfns.c b/src/editfns.c index 4ea70253793..191a9ab8f8a 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -1743,10 +1743,10 @@ disassemble_lisp_time (Lisp_Object specified_time, Lisp_Object *phigh, | |||
| 1743 | 1743 | ||
| 1744 | /* When combining components, require LOW to be an integer, | 1744 | /* When combining components, require LOW to be an integer, |
| 1745 | as otherwise it would be a pain to add up times. */ | 1745 | as otherwise it would be a pain to add up times. */ |
| 1746 | if (! FIXNUMP (low)) | 1746 | if (! INTEGERP (low)) |
| 1747 | return 0; | 1747 | return 0; |
| 1748 | } | 1748 | } |
| 1749 | else if (FIXNUMP (specified_time)) | 1749 | else if (INTEGERP (specified_time)) |
| 1750 | len = 2; | 1750 | len = 2; |
| 1751 | 1751 | ||
| 1752 | *phigh = high; | 1752 | *phigh = high; |
| @@ -1807,11 +1807,12 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, | |||
| 1807 | Lisp_Object psec, | 1807 | Lisp_Object psec, |
| 1808 | struct lisp_time *result, double *dresult) | 1808 | struct lisp_time *result, double *dresult) |
| 1809 | { | 1809 | { |
| 1810 | EMACS_INT hi, lo, us, ps; | 1810 | EMACS_INT hi, us, ps; |
| 1811 | intmax_t lo; | ||
| 1811 | if (! (FIXNUMP (high) | 1812 | if (! (FIXNUMP (high) |
| 1812 | && FIXNUMP (usec) && FIXNUMP (psec))) | 1813 | && FIXNUMP (usec) && FIXNUMP (psec))) |
| 1813 | return 0; | 1814 | return 0; |
| 1814 | if (! FIXNUMP (low)) | 1815 | if (! INTEGERP (low)) |
| 1815 | { | 1816 | { |
| 1816 | if (FLOATP (low)) | 1817 | if (FLOATP (low)) |
| 1817 | { | 1818 | { |
| @@ -1841,7 +1842,8 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, | |||
| 1841 | } | 1842 | } |
| 1842 | 1843 | ||
| 1843 | hi = XFIXNUM (high); | 1844 | hi = XFIXNUM (high); |
| 1844 | lo = XFIXNUM (low); | 1845 | if (! integer_to_intmax (low, &lo)) |
| 1846 | return -1; | ||
| 1845 | us = XFIXNUM (usec); | 1847 | us = XFIXNUM (usec); |
| 1846 | ps = XFIXNUM (psec); | 1848 | ps = XFIXNUM (psec); |
| 1847 | 1849 | ||
| @@ -1849,7 +1851,8 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, | |||
| 1849 | each overflow into the next higher-order component. */ | 1851 | each overflow into the next higher-order component. */ |
| 1850 | us += ps / 1000000 - (ps % 1000000 < 0); | 1852 | us += ps / 1000000 - (ps % 1000000 < 0); |
| 1851 | lo += us / 1000000 - (us % 1000000 < 0); | 1853 | lo += us / 1000000 - (us % 1000000 < 0); |
| 1852 | hi += lo >> LO_TIME_BITS; | 1854 | if (INT_ADD_WRAPV (lo >> LO_TIME_BITS, hi, &hi)) |
| 1855 | return -1; | ||
| 1853 | ps = ps % 1000000 + 1000000 * (ps % 1000000 < 0); | 1856 | ps = ps % 1000000 + 1000000 * (ps % 1000000 < 0); |
| 1854 | us = us % 1000000 + 1000000 * (us % 1000000 < 0); | 1857 | us = us % 1000000 + 1000000 * (us % 1000000 < 0); |
| 1855 | lo &= (1 << LO_TIME_BITS) - 1; | 1858 | lo &= (1 << LO_TIME_BITS) - 1; |