diff options
| author | Paul Eggert | 2015-02-08 16:21:11 -0800 |
|---|---|---|
| committer | Paul Eggert | 2015-02-08 16:21:44 -0800 |
| commit | fd6f7d1449c8496ab5c019d2aad7ca5e2980713a (patch) | |
| tree | 83934f904dda8a258d8b8175d0f6120f510b3790 /src | |
| parent | db3fc07caf71b6d7a34f80333ba54ed6d67ee144 (diff) | |
| download | emacs-fd6f7d1449c8496ab5c019d2aad7ca5e2980713a.tar.gz emacs-fd6f7d1449c8496ab5c019d2aad7ca5e2980713a.zip | |
Better distinguish infinite from invalid times
* editfns.c (check_time_validity): New function.
(decode_time_components): Return int, not bool.
Return -1 (not 0) if the time is out of range.
All callers changed.
(lisp_time_struct, lisp_seconds_argument): Distinguish better
between time overflow and invalid time values.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/editfns.c | 58 | ||||
| -rw-r--r-- | src/keyboard.c | 11 | ||||
| -rw-r--r-- | src/systime.h | 4 |
4 files changed, 56 insertions, 27 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 56f88f5bec4..017b8f15e3b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2015-02-09 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Better distinguish infinite from invalid times | ||
| 4 | * editfns.c (check_time_validity): New function. | ||
| 5 | (decode_time_components): Return int, not bool. | ||
| 6 | Return -1 (not 0) if the time is out of range. | ||
| 7 | All callers changed. | ||
| 8 | (lisp_time_struct, lisp_seconds_argument): Distinguish better | ||
| 9 | between time overflow and invalid time values. | ||
| 10 | |||
| 1 | 2015-02-08 Paul Eggert <eggert@cs.ucla.edu> | 11 | 2015-02-08 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 12 | ||
| 3 | Minor tweaks to frame_size_history_add | 13 | Minor tweaks to frame_size_history_add |
diff --git a/src/editfns.c b/src/editfns.c index 7026ccc084e..c205ca3688f 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -1395,6 +1395,19 @@ invalid_time (void) | |||
| 1395 | error ("Invalid time specification"); | 1395 | error ("Invalid time specification"); |
| 1396 | } | 1396 | } |
| 1397 | 1397 | ||
| 1398 | /* Check a return value compatible with that of decode_time_components. */ | ||
| 1399 | static void | ||
| 1400 | check_time_validity (int validity) | ||
| 1401 | { | ||
| 1402 | if (validity <= 0) | ||
| 1403 | { | ||
| 1404 | if (validity < 0) | ||
| 1405 | time_overflow (); | ||
| 1406 | else | ||
| 1407 | invalid_time (); | ||
| 1408 | } | ||
| 1409 | } | ||
| 1410 | |||
| 1398 | /* A substitute for mktime_z on platforms that lack it. It's not | 1411 | /* A substitute for mktime_z on platforms that lack it. It's not |
| 1399 | thread-safe, but should be good enough for Emacs in typical use. */ | 1412 | thread-safe, but should be good enough for Emacs in typical use. */ |
| 1400 | #ifndef HAVE_TZALLOC | 1413 | #ifndef HAVE_TZALLOC |
| @@ -1698,9 +1711,9 @@ decode_float_time (double t, struct lisp_time *result) | |||
| 1698 | If *DRESULT is not null, store into *DRESULT the number of | 1711 | If *DRESULT is not null, store into *DRESULT the number of |
| 1699 | seconds since the start of the POSIX Epoch. | 1712 | seconds since the start of the POSIX Epoch. |
| 1700 | 1713 | ||
| 1701 | Return true if successful, false if the components are of the | 1714 | Return 1 if successful, 0 if the components are of the |
| 1702 | wrong type or represent a time out of range. */ | 1715 | wrong type, and -1 if the time is out of range. */ |
| 1703 | bool | 1716 | int |
| 1704 | decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, | 1717 | decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, |
| 1705 | Lisp_Object psec, | 1718 | Lisp_Object psec, |
| 1706 | struct lisp_time *result, double *dresult) | 1719 | struct lisp_time *result, double *dresult) |
| @@ -1708,17 +1721,17 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, | |||
| 1708 | EMACS_INT hi, lo, us, ps; | 1721 | EMACS_INT hi, lo, us, ps; |
| 1709 | if (! (INTEGERP (high) | 1722 | if (! (INTEGERP (high) |
| 1710 | && INTEGERP (usec) && INTEGERP (psec))) | 1723 | && INTEGERP (usec) && INTEGERP (psec))) |
| 1711 | return false; | 1724 | return 0; |
| 1712 | if (! INTEGERP (low)) | 1725 | if (! INTEGERP (low)) |
| 1713 | { | 1726 | { |
| 1714 | if (FLOATP (low)) | 1727 | if (FLOATP (low)) |
| 1715 | { | 1728 | { |
| 1716 | double t = XFLOAT_DATA (low); | 1729 | double t = XFLOAT_DATA (low); |
| 1717 | if (result && ! decode_float_time (t, result)) | 1730 | if (result && ! decode_float_time (t, result)) |
| 1718 | return false; | 1731 | return -1; |
| 1719 | if (dresult) | 1732 | if (dresult) |
| 1720 | *dresult = t; | 1733 | *dresult = t; |
| 1721 | return true; | 1734 | return 1; |
| 1722 | } | 1735 | } |
| 1723 | else if (NILP (low)) | 1736 | else if (NILP (low)) |
| 1724 | { | 1737 | { |
| @@ -1732,10 +1745,10 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, | |||
| 1732 | } | 1745 | } |
| 1733 | if (dresult) | 1746 | if (dresult) |
| 1734 | *dresult = now.tv_sec + now.tv_nsec / 1e9; | 1747 | *dresult = now.tv_sec + now.tv_nsec / 1e9; |
| 1735 | return true; | 1748 | return 1; |
| 1736 | } | 1749 | } |
| 1737 | else | 1750 | else |
| 1738 | return false; | 1751 | return 0; |
| 1739 | } | 1752 | } |
| 1740 | 1753 | ||
| 1741 | hi = XINT (high); | 1754 | hi = XINT (high); |
| @@ -1755,7 +1768,7 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, | |||
| 1755 | if (result) | 1768 | if (result) |
| 1756 | { | 1769 | { |
| 1757 | if (! (MOST_NEGATIVE_FIXNUM <= hi && hi <= MOST_POSITIVE_FIXNUM)) | 1770 | if (! (MOST_NEGATIVE_FIXNUM <= hi && hi <= MOST_POSITIVE_FIXNUM)) |
| 1758 | return false; | 1771 | return -1; |
| 1759 | result->hi = hi; | 1772 | result->hi = hi; |
| 1760 | result->lo = lo; | 1773 | result->lo = lo; |
| 1761 | result->us = us; | 1774 | result->us = us; |
| @@ -1768,7 +1781,7 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, | |||
| 1768 | *dresult = (us * 1e6 + ps) / 1e12 + lo + dhi * (1 << LO_TIME_BITS); | 1781 | *dresult = (us * 1e6 + ps) / 1e12 + lo + dhi * (1 << LO_TIME_BITS); |
| 1769 | } | 1782 | } |
| 1770 | 1783 | ||
| 1771 | return true; | 1784 | return 1; |
| 1772 | } | 1785 | } |
| 1773 | 1786 | ||
| 1774 | struct timespec | 1787 | struct timespec |
| @@ -1792,8 +1805,8 @@ lisp_time_struct (Lisp_Object specified_time, int *plen) | |||
| 1792 | Lisp_Object high, low, usec, psec; | 1805 | Lisp_Object high, low, usec, psec; |
| 1793 | struct lisp_time t; | 1806 | struct lisp_time t; |
| 1794 | int len = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec); | 1807 | int len = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec); |
| 1795 | if (! (len && decode_time_components (high, low, usec, psec, &t, 0))) | 1808 | int val = len ? decode_time_components (high, low, usec, psec, &t, 0) : 0; |
| 1796 | invalid_time (); | 1809 | check_time_validity (val); |
| 1797 | *plen = len; | 1810 | *plen = len; |
| 1798 | return t; | 1811 | return t; |
| 1799 | } | 1812 | } |
| @@ -1818,13 +1831,20 @@ lisp_seconds_argument (Lisp_Object specified_time) | |||
| 1818 | { | 1831 | { |
| 1819 | Lisp_Object high, low, usec, psec; | 1832 | Lisp_Object high, low, usec, psec; |
| 1820 | struct lisp_time t; | 1833 | struct lisp_time t; |
| 1821 | if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec) | 1834 | |
| 1822 | && decode_time_components (high, low, make_number (0), | 1835 | int val = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec); |
| 1823 | make_number (0), &t, 0))) | 1836 | if (val != 0) |
| 1824 | invalid_time (); | 1837 | { |
| 1825 | if (! ((TYPE_SIGNED (time_t) ? TIME_T_MIN >> LO_TIME_BITS <= t.hi : 0 <= t.hi) | 1838 | val = decode_time_components (high, low, make_number (0), |
| 1826 | && t.hi <= TIME_T_MAX >> LO_TIME_BITS)) | 1839 | make_number (0), &t, 0); |
| 1827 | time_overflow (); | 1840 | if (0 < val |
| 1841 | && ! ((TYPE_SIGNED (time_t) | ||
| 1842 | ? TIME_T_MIN >> LO_TIME_BITS <= t.hi | ||
| 1843 | : 0 <= t.hi) | ||
| 1844 | && t.hi <= TIME_T_MAX >> LO_TIME_BITS)) | ||
| 1845 | val = -1; | ||
| 1846 | } | ||
| 1847 | check_time_validity (val); | ||
| 1828 | return (t.hi << LO_TIME_BITS) + t.lo; | 1848 | return (t.hi << LO_TIME_BITS) + t.lo; |
| 1829 | } | 1849 | } |
| 1830 | 1850 | ||
diff --git a/src/keyboard.c b/src/keyboard.c index 1176d701f2a..ee621923c67 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -4369,19 +4369,18 @@ Lisp_Object pending_funcalls; | |||
| 4369 | static bool | 4369 | static bool |
| 4370 | decode_timer (Lisp_Object timer, struct timespec *result) | 4370 | decode_timer (Lisp_Object timer, struct timespec *result) |
| 4371 | { | 4371 | { |
| 4372 | Lisp_Object *vector; | 4372 | Lisp_Object *vec; |
| 4373 | 4373 | ||
| 4374 | if (! (VECTORP (timer) && ASIZE (timer) == 9)) | 4374 | if (! (VECTORP (timer) && ASIZE (timer) == 9)) |
| 4375 | return 0; | 4375 | return 0; |
| 4376 | vector = XVECTOR (timer)->contents; | 4376 | vec = XVECTOR (timer)->contents; |
| 4377 | if (! NILP (vector[0])) | 4377 | if (! NILP (vec[0])) |
| 4378 | return 0; | 4378 | return 0; |
| 4379 | if (! INTEGERP (vector[2])) | 4379 | if (! INTEGERP (vec[2])) |
| 4380 | return false; | 4380 | return false; |
| 4381 | 4381 | ||
| 4382 | struct lisp_time t; | 4382 | struct lisp_time t; |
| 4383 | if (! decode_time_components (vector[1], vector[2], vector[3], vector[8], | 4383 | if (decode_time_components (vec[1], vec[2], vec[3], vec[8], &t, 0) <= 0) |
| 4384 | &t, 0)) | ||
| 4385 | return false; | 4384 | return false; |
| 4386 | *result = lisp_to_timespec (t); | 4385 | *result = lisp_to_timespec (t); |
| 4387 | return timespec_valid_p (*result); | 4386 | return timespec_valid_p (*result); |
diff --git a/src/systime.h b/src/systime.h index 1d3a4ba2914..4787c512aaa 100644 --- a/src/systime.h +++ b/src/systime.h | |||
| @@ -100,8 +100,8 @@ struct lisp_time | |||
| 100 | 100 | ||
| 101 | /* defined in editfns.c */ | 101 | /* defined in editfns.c */ |
| 102 | extern Lisp_Object make_lisp_time (struct timespec); | 102 | extern Lisp_Object make_lisp_time (struct timespec); |
| 103 | extern bool decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object, | 103 | extern int decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object, |
| 104 | Lisp_Object, struct lisp_time *, double *); | 104 | Lisp_Object, struct lisp_time *, double *); |
| 105 | extern struct timespec lisp_to_timespec (struct lisp_time); | 105 | extern struct timespec lisp_to_timespec (struct lisp_time); |
| 106 | extern struct timespec lisp_time_argument (Lisp_Object); | 106 | extern struct timespec lisp_time_argument (Lisp_Object); |
| 107 | #endif | 107 | #endif |