diff options
| author | Paul Eggert | 2011-03-12 22:27:18 -0800 |
|---|---|---|
| committer | Paul Eggert | 2011-03-12 22:27:18 -0800 |
| commit | 313c1e544ab88d0ca95015b30e23dfbabe36a2ac (patch) | |
| tree | 8433b2864d93515d7ad5e5f666fe6ab141d007e3 | |
| parent | 803110b53623077719e4a9d301e416f31007c946 (diff) | |
| download | emacs-313c1e544ab88d0ca95015b30e23dfbabe36a2ac.tar.gz emacs-313c1e544ab88d0ca95015b30e23dfbabe36a2ac.zip | |
* editfns.c (lisp_time_argument): Check for time stamp overflow.
| -rw-r--r-- | src/ChangeLog | 4 | ||||
| -rw-r--r-- | src/editfns.c | 33 |
2 files changed, 30 insertions, 7 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index b3362b9fbca..546b02d2a96 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | 2011-03-13 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | * editfns.c (lisp_time_argument): Check for time stamp overflow. | ||
| 4 | |||
| 1 | 2011-03-12 Paul Eggert <eggert@cs.ucla.edu> | 5 | 2011-03-12 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 6 | ||
| 3 | Improve quality of tests for time stamp overflow. For example, | 7 | Improve quality of tests for time stamp overflow. For example, |
diff --git a/src/editfns.c b/src/editfns.c index e55502bdb89..d92d3482d09 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -1439,12 +1439,17 @@ static EMACS_INT | |||
| 1439 | hi_time (time_t t) | 1439 | hi_time (time_t t) |
| 1440 | { | 1440 | { |
| 1441 | time_t hi = t >> 16; | 1441 | time_t hi = t >> 16; |
| 1442 | if ((TYPE_SIGNED (time_t) | 1442 | |
| 1443 | && TIME_T_MIN >> 16 < MOST_NEGATIVE_FIXNUM | 1443 | /* Check for overflow, helping the compiler for common cases where |
| 1444 | && hi < MOST_NEGATIVE_FIXNUM) | 1444 | no runtime check is needed, and taking care not to convert |
| 1445 | || (MOST_POSITIVE_FIXNUM < TIME_T_MAX >> 16 | 1445 | negative numbers to unsigned before comparing them. */ |
| 1446 | && MOST_POSITIVE_FIXNUM < hi)) | 1446 | if (! ((! TYPE_SIGNED (time_t) |
| 1447 | || MOST_NEGATIVE_FIXNUM <= TIME_T_MIN >> 16 | ||
| 1448 | || MOST_NEGATIVE_FIXNUM <= hi) | ||
| 1449 | && (TIME_T_MAX >> 16 <= MOST_POSITIVE_FIXNUM | ||
| 1450 | || hi <= MOST_POSITIVE_FIXNUM))) | ||
| 1447 | time_overflow (); | 1451 | time_overflow (); |
| 1452 | |||
| 1448 | return hi; | 1453 | return hi; |
| 1449 | } | 1454 | } |
| 1450 | 1455 | ||
| @@ -1551,6 +1556,7 @@ lisp_time_argument (Lisp_Object specified_time, time_t *result, int *usec) | |||
| 1551 | else | 1556 | else |
| 1552 | { | 1557 | { |
| 1553 | Lisp_Object high, low; | 1558 | Lisp_Object high, low; |
| 1559 | EMACS_INT hi; | ||
| 1554 | high = Fcar (specified_time); | 1560 | high = Fcar (specified_time); |
| 1555 | CHECK_NUMBER (high); | 1561 | CHECK_NUMBER (high); |
| 1556 | low = Fcdr (specified_time); | 1562 | low = Fcdr (specified_time); |
| @@ -1574,8 +1580,21 @@ lisp_time_argument (Lisp_Object specified_time, time_t *result, int *usec) | |||
| 1574 | else if (usec) | 1580 | else if (usec) |
| 1575 | *usec = 0; | 1581 | *usec = 0; |
| 1576 | CHECK_NUMBER (low); | 1582 | CHECK_NUMBER (low); |
| 1577 | *result = (XINT (high) << 16) + (XINT (low) & 0xffff); | 1583 | hi = XINT (high); |
| 1578 | return *result >> 16 == XINT (high); | 1584 | |
| 1585 | /* Check for overflow, helping the compiler for common cases | ||
| 1586 | where no runtime check is needed, and taking care not to | ||
| 1587 | convert negative numbers to unsigned before comparing them. */ | ||
| 1588 | if (! ((TYPE_SIGNED (time_t) | ||
| 1589 | ? (TIME_T_MIN >> 16 <= MOST_NEGATIVE_FIXNUM | ||
| 1590 | || TIME_T_MIN >> 16 <= hi) | ||
| 1591 | : 0 <= hi) | ||
| 1592 | && (MOST_POSITIVE_FIXNUM <= TIME_T_MAX >> 16 | ||
| 1593 | || hi <= TIME_T_MAX >> 16))) | ||
| 1594 | return 0; | ||
| 1595 | |||
| 1596 | *result = (hi << 16) + (XINT (low) & 0xffff); | ||
| 1597 | return 1; | ||
| 1579 | } | 1598 | } |
| 1580 | } | 1599 | } |
| 1581 | 1600 | ||