aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2018-09-04 19:14:01 -0700
committerPaul Eggert2018-09-04 19:15:57 -0700
commitccb3891ff5446b578b9306aec0fd9c5ec3ed8e98 (patch)
tree888bda0e0584ef78d2a3b25cc6c03b35b6b8ea8e /src
parentecb985c10d5241a65ab9552ebfcecaa150b35427 (diff)
downloademacs-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.c15
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;