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/editfns.c | |
| 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/editfns.c')
| -rw-r--r-- | src/editfns.c | 58 |
1 files changed, 39 insertions, 19 deletions
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 | ||