mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-31 15:01:09 +00:00
mktime: avoid signed integer overflow
* time/mktime.c (__mktime_internal): Do not mishandle the case where diff == INT_MIN.
This commit is contained in:
parent
94c7d826c9
commit
f8591f8049
@ -1,5 +1,9 @@
|
|||||||
2012-05-23 Paul Eggert <eggert@cs.ucla.edu>
|
2012-05-23 Paul Eggert <eggert@cs.ucla.edu>
|
||||||
|
|
||||||
|
mktime: avoid signed integer overflow
|
||||||
|
* time/mktime.c (__mktime_internal): Do not mishandle the case
|
||||||
|
where diff == INT_MIN.
|
||||||
|
|
||||||
mktime: simplify computation of average
|
mktime: simplify computation of average
|
||||||
* time/mktime.c (ranged_convert): Use new time_t_avg function
|
* time/mktime.c (ranged_convert): Use new time_t_avg function
|
||||||
instead of rolling our own (probably-slower) code.
|
instead of rolling our own (probably-slower) code.
|
||||||
|
@ -445,7 +445,7 @@ __mktime_internal (struct tm *tp,
|
|||||||
|
|
||||||
int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM);
|
int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM);
|
||||||
int diff = approx_biennia - approx_requested_biennia;
|
int diff = approx_biennia - approx_requested_biennia;
|
||||||
int abs_diff = diff < 0 ? - diff : diff;
|
int approx_abs_diff = diff < 0 ? -1 - diff : diff;
|
||||||
|
|
||||||
/* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously
|
/* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously
|
||||||
gives a positive value of 715827882. Setting a variable
|
gives a positive value of 715827882. Setting a variable
|
||||||
@ -456,15 +456,15 @@ __mktime_internal (struct tm *tp,
|
|||||||
time_t overflow_threshold =
|
time_t overflow_threshold =
|
||||||
(time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM;
|
(time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM;
|
||||||
|
|
||||||
if (overflow_threshold < abs_diff)
|
if (overflow_threshold < approx_abs_diff)
|
||||||
{
|
{
|
||||||
/* Overflow occurred. Try repairing it; this might work if
|
/* Overflow occurred. Try repairing it; this might work if
|
||||||
the time zone offset is enough to undo the overflow. */
|
the time zone offset is enough to undo the overflow. */
|
||||||
time_t repaired_t0 = -1 - t0;
|
time_t repaired_t0 = -1 - t0;
|
||||||
approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
|
approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
|
||||||
diff = approx_biennia - approx_requested_biennia;
|
diff = approx_biennia - approx_requested_biennia;
|
||||||
abs_diff = diff < 0 ? - diff : diff;
|
approx_abs_diff = diff < 0 ? -1 - diff : diff;
|
||||||
if (overflow_threshold < abs_diff)
|
if (overflow_threshold < approx_abs_diff)
|
||||||
return -1;
|
return -1;
|
||||||
guessed_offset += repaired_t0 - t0;
|
guessed_offset += repaired_t0 - t0;
|
||||||
t0 = repaired_t0;
|
t0 = repaired_t0;
|
||||||
|
Loading…
Reference in New Issue
Block a user