]> granicus.if.org Git - php/commitdiff
- Fixed bug #52668 (Iterating over a dateperiod twice is broken).
authorDerick Rethans <derick@php.net>
Mon, 30 Aug 2010 15:32:09 +0000 (15:32 +0000)
committerDerick Rethans <derick@php.net>
Mon, 30 Aug 2010 15:32:09 +0000 (15:32 +0000)
ext/date/lib/timelib.c
ext/date/lib/timelib.h
ext/date/php_date.c
ext/date/php_date.h
ext/date/tests/bug52668.phpt [new file with mode: 0644]

index 727e6671b993e70c5bec3859341ca48b2a75e260..528c89d63a108441d1f1c3dc547994820acd5dfe 100644 (file)
@@ -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();
index 81d5b8b1c1a7dfbd0ac851a424dc1665beb71587..c79fa9a46996d2f7b3435a485220ccacfbd08dce 100644 (file)
@@ -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);
index 87403be5251a47543bea36ca7bc1bb75c5cd8161..e6d14fd27e802ed065f2d2dd0ca630df1b7549e4 100644 (file)
@@ -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;
                }
        }
index 21c0c581ed56a5e75136cac74c3d44e9bed66345..09755060c2c9216aecd1f1eee6cebf89bc325a7f 100644 (file)
@@ -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 (file)
index 0000000..307a426
--- /dev/null
@@ -0,0 +1,25 @@
+--TEST--
+Bug #52668 (Iterating over a dateperiod twice is broken)
+--INI--
+date.timezone=UTC
+--FILE--
+<?php
+$start    = new DateTime('20101212');
+$interval = DateInterval::createFromDateString('next day');
+$dp = new DatePeriod($start, $interval, 1);
+foreach($dp as $dt) {
+    echo $dt->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