diff options
author | Derick Rethans <derick@php.net> | 2009-05-03 18:22:40 +0000 |
---|---|---|
committer | Derick Rethans <derick@php.net> | 2009-05-03 18:22:40 +0000 |
commit | febc2763dd872d484ed7df09f778a0a85104102a (patch) | |
tree | 8a8b86fea5dd273a9b8901f96e2a17d09c5d8059 /ext/date/lib/tm2unixtime.c | |
parent | 7e0387dbde7f0d3da6c948b29f036dedb4bbc248 (diff) | |
download | php-git-febc2763dd872d484ed7df09f778a0a85104102a.tar.gz |
- MFH: Fixed bug #48058 (Year formatter goes wrong with out-of-int range).
- MFH: Fixed bug #45822 (Near infinite-loops while parsing huge relative offsets).
Diffstat (limited to 'ext/date/lib/tm2unixtime.c')
-rw-r--r-- | ext/date/lib/tm2unixtime.c | 22 |
1 files changed, 10 insertions, 12 deletions
diff --git a/ext/date/lib/tm2unixtime.c b/ext/date/lib/tm2unixtime.c index 6d0684b018..6b737141fb 100644 --- a/ext/date/lib/tm2unixtime.c +++ b/ext/date/lib/tm2unixtime.c @@ -31,20 +31,12 @@ static int days_in_month[13] = { 31, 31, 28, 31, 30, 31, 30, 31, 3 static int do_range_limit(timelib_sll start, timelib_sll end, timelib_sll adj, timelib_sll *a, timelib_sll *b) { if (*a < start) { - *a += adj; - (*b)--; - return 1; + *b -= (start - *a - 1) / adj + 1; + *a += adj * ((start - *a - 1) / adj + 1); } if (*a >= end) { - if (start == 0) { - (*b) += (*a / end); - (*a) -= (end * (*a / end)); - return 0; - } - - *a -= adj; - (*b)++; - return 1; + *b += *a / adj; + *a -= adj * (*a / adj); } return 0; } @@ -90,6 +82,12 @@ static int do_range_limit_days(timelib_sll *y, timelib_sll *m, timelib_sll *d) timelib_sll days_this_month; timelib_sll last_month, last_year; timelib_sll days_last_month; + + /* can jump an entire leap year period quickly */ + if (*d >= DAYS_PER_LYEAR_PERIOD || *d <= -DAYS_PER_LYEAR_PERIOD) { + *y += YEARS_PER_LYEAR_PERIOD * (*d / DAYS_PER_LYEAR_PERIOD); + *d -= DAYS_PER_LYEAR_PERIOD * (*d / DAYS_PER_LYEAR_PERIOD); + } do_range_limit(1, 13, 12, m, y); |