From: Derick Rethans Date: Mon, 30 Aug 2010 15:32:09 +0000 (+0000) Subject: - Fixed bug #52668 (Iterating over a dateperiod twice is broken). X-Git-Tag: php-5.4.0alpha1~191^2~1031 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ab6789a0eff4f1c4ae86fc038a53be87abca1efb;p=php - Fixed bug #52668 (Iterating over a dateperiod twice is broken). --- diff --git a/ext/date/lib/timelib.c b/ext/date/lib/timelib.c index 727e6671b9..528c89d63a 100644 --- a/ext/date/lib/timelib.c +++ b/ext/date/lib/timelib.c @@ -46,6 +46,19 @@ timelib_rel_time* timelib_rel_time_ctor(void) return t; } +timelib_time* timelib_time_clone(timelib_time *orig) +{ + timelib_time *tmp = timelib_time_ctor(); + memcpy(tmp, orig, sizeof(timelib_time)); + if (orig->tz_abbr) { + tmp->tz_abbr = strdup(orig->tz_abbr); + } + if (orig->tz_info) { + tmp->tz_info = orig->tz_info; + } + return tmp; +} + timelib_rel_time* timelib_rel_time_clone(timelib_rel_time *rel) { timelib_rel_time *tmp = timelib_rel_time_ctor(); diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h index 81d5b8b1c1..c79fa9a469 100644 --- a/ext/date/lib/timelib.h +++ b/ext/date/lib/timelib.h @@ -109,6 +109,7 @@ timelib_rel_time* timelib_rel_time_clone(timelib_rel_time *tz); timelib_time* timelib_time_ctor(void); void timelib_time_set_option(timelib_time* tm, int option, void* option_value); void timelib_time_dtor(timelib_time* t); +timelib_time* timelib_time_clone(timelib_time* orig); timelib_time_offset* timelib_time_offset_ctor(void); void timelib_time_offset_dtor(timelib_time_offset* t); diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 87403be525..e6d14fd27e 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -1821,7 +1821,7 @@ static int date_period_it_has_more(zend_object_iterator *iter TSRMLS_DC) { date_period_it *iterator = (date_period_it *)iter; php_period_obj *object = iterator->object; - timelib_time *it_time = object->start; + timelib_time *it_time = object->current; /* apply modification if it's not the first iteration */ if (!object->include_start_date || iterator->current_index > 0) { @@ -1833,7 +1833,7 @@ static int date_period_it_has_more(zend_object_iterator *iter TSRMLS_DC) } if (object->end) { - return object->start->sse < object->end->sse ? SUCCESS : FAILURE; + return object->current->sse < object->end->sse ? SUCCESS : FAILURE; } else { return (iterator->current_index < object->recurrences) ? SUCCESS : FAILURE; } @@ -1846,7 +1846,7 @@ static void date_period_it_current_data(zend_object_iterator *iter, zval ***data { date_period_it *iterator = (date_period_it *)iter; php_period_obj *object = iterator->object; - timelib_time *it_time = object->start; + timelib_time *it_time = object->current; php_date_obj *newdateobj; /* Create new object */ @@ -1894,6 +1894,10 @@ static void date_period_it_rewind(zend_object_iterator *iter TSRMLS_DC) date_period_it *iterator = (date_period_it *)iter; iterator->current_index = 0; + if (iterator->object->current) { + timelib_time_dtor(iterator->object->current); + } + iterator->object->current = timelib_time_clone(iterator->object->start); date_period_it_invalidate_current(iter TSRMLS_CC); } /* }}} */ @@ -2330,6 +2334,10 @@ static void date_object_free_storage_period(void *object TSRMLS_DC) timelib_time_dtor(intern->start); } + if (intern->current) { + timelib_time_dtor(intern->current); + } + if (intern->end) { timelib_time_dtor(intern->end); } @@ -3708,6 +3716,7 @@ PHP_METHOD(DatePeriod, __construct) } dpobj = zend_object_store_get_object(getThis() TSRMLS_CC); + dpobj->current = NULL; if (isostr_len) { date_period_initialize(&(dpobj->start), &(dpobj->end), &(dpobj->interval), (int*) &recurrences, isostr, isostr_len TSRMLS_CC); @@ -3749,14 +3758,7 @@ PHP_METHOD(DatePeriod, __construct) /* end date */ if (end) { dateobj = (php_date_obj *) zend_object_store_get_object(end TSRMLS_CC); - clone = timelib_time_ctor(); - memcpy(clone, dateobj->time, sizeof(timelib_time)); - if (dateobj->time->tz_abbr) { - clone->tz_abbr = strdup(dateobj->time->tz_abbr); - } - if (dateobj->time->tz_info) { - clone->tz_info = dateobj->time->tz_info; - } + clone = timelib_time_clone(dateobj->time); dpobj->end = clone; } } diff --git a/ext/date/php_date.h b/ext/date/php_date.h index 21c0c581ed..09755060c2 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -139,6 +139,7 @@ struct _php_interval_obj { struct _php_period_obj { zend_object std; timelib_time *start; + timelib_time *current; timelib_time *end; timelib_rel_time *interval; int recurrences; diff --git a/ext/date/tests/bug52668.phpt b/ext/date/tests/bug52668.phpt new file mode 100644 index 0000000000..307a4264dd --- /dev/null +++ b/ext/date/tests/bug52668.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #52668 (Iterating over a dateperiod twice is broken) +--INI-- +date.timezone=UTC +--FILE-- +format('r') . "\n"; // Sun, 12 Dec 2010 00:00:00 +0100 +} +echo $start->format('r'), "\n"; +foreach($dp as $dt) { + echo $dt->format('r') . "\n"; // Sun, 12 Dec 2010 00:00:00 +0100 +} +echo $start->format('r'), "\n\n"; +?> +--EXPECT-- +Sun, 12 Dec 2010 00:00:00 +0000 +Mon, 13 Dec 2010 00:00:00 +0000 +Sun, 12 Dec 2010 00:00:00 +0000 +Sun, 12 Dec 2010 00:00:00 +0000 +Mon, 13 Dec 2010 00:00:00 +0000 +Sun, 12 Dec 2010 00:00:00 +0000