summaryrefslogtreecommitdiff
path: root/ext/date/lib/tm2unixtime.c
diff options
context:
space:
mode:
authorDerick Rethans <derick@php.net>2009-05-03 18:22:40 +0000
committerDerick Rethans <derick@php.net>2009-05-03 18:22:40 +0000
commitfebc2763dd872d484ed7df09f778a0a85104102a (patch)
tree8a8b86fea5dd273a9b8901f96e2a17d09c5d8059 /ext/date/lib/tm2unixtime.c
parent7e0387dbde7f0d3da6c948b29f036dedb4bbc248 (diff)
downloadphp-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.c22
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);