]> granicus.if.org Git - php/commitdiff
Fixed #74639 - Added proper clone functionality for DatePeriod and DateInterval
authorandrewnester <andrew.nester.dev@gmail.com>
Fri, 26 May 2017 10:56:41 +0000 (13:56 +0300)
committerJoe Watkins <krakjoe@php.net>
Thu, 1 Jun 2017 07:07:11 +0000 (08:07 +0100)
NEWS
ext/date/php_date.c
ext/date/tests/bug74639.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index ce6b60f5f67d7d6573b11fb95e6c48596c22784c..4735dd47a4a01a43a23b21224f48ab059ab86212 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,10 @@ PHP                                                                        NEWS
     properties). (Laruence)
   . Fixed misparsing of abstract unix domain socket names. (Sara)
 
+- Date:
+  . Fixed bug #74639 (implement clone for DatePeriod and DateInterval).
+    (andrewnester)
+
 - Mbstring:
   . Add oniguruma upstream fix (CVE-2017-9224, CVE-2017-9226, CVE-2017-9227,
     CVE-2017-9228, CVE-2017-9229) (Remi, Mamoru TASAKA)
index c4e5fcb50bc89be2cae743a5d18145f1c3f74698..dd6ca22fba311f9263f54ceb4ea0b8f19bc5ff17 100644 (file)
@@ -2397,8 +2397,11 @@ static zend_object *date_object_clone_interval(zval *this_ptr) /* {{{ */
        php_interval_obj *new_obj = php_interval_obj_from_obj(date_object_new_interval_ex(old_obj->std.ce, 0));
 
        zend_objects_clone_members(&new_obj->std, &old_obj->std);
+       new_obj->initialized = old_obj->initialized;
+       if (old_obj->diff) {
+               new_obj->diff = timelib_rel_time_clone(old_obj->diff);
+       }
 
-       /** FIX ME ADD CLONE STUFF **/
        return &new_obj->std;
 } /* }}} */
 
@@ -2481,8 +2484,23 @@ static zend_object *date_object_clone_period(zval *this_ptr) /* {{{ */
        php_period_obj *new_obj = php_period_obj_from_obj(date_object_new_period_ex(old_obj->std.ce, 0));
 
        zend_objects_clone_members(&new_obj->std, &old_obj->std);
-
-       /** FIX ME ADD CLONE STUFF **/
+       new_obj->initialized = old_obj->initialized;
+       new_obj->recurrences = old_obj->recurrences;
+       new_obj->include_start_date = old_obj->include_start_date;
+       new_obj->start_ce = old_obj->start_ce;
+
+       if (old_obj->start) {
+               new_obj->start = timelib_time_clone(old_obj->start);
+       }
+       if (old_obj->current) {
+               new_obj->current = timelib_time_clone(old_obj->current);
+       }
+       if (old_obj->end) {
+        new_obj->end = timelib_time_clone(old_obj->end);
+    }
+    if (old_obj->interval) {
+        new_obj->interval = timelib_rel_time_clone(old_obj->interval);
+    }
        return &new_obj->std;
 } /* }}} */
 
diff --git a/ext/date/tests/bug74639.phpt b/ext/date/tests/bug74639.phpt
new file mode 100644 (file)
index 0000000..43eccc9
--- /dev/null
@@ -0,0 +1,33 @@
+--TEST--
+Bug #74639 Cloning DatePeriod leads to segfault
+--FILE--
+<?php
+
+$start = new DateTime('2017-05-22 09:00:00');
+$end = new DateTime('2017-08-24 18:00:00');
+$interval = $start->diff($end);
+
+$period = new DatePeriod($start, $interval, $end);
+$clonedPeriod = clone $period;
+$clonedInterval = clone $interval;
+
+if ($period->getStartDate() != $clonedPeriod->getStartDate()) {
+    echo "failure\n";
+}
+
+if ($period->getEndDate() != $clonedPeriod->getEndDate()) {
+    echo "failure\n";
+}
+
+if ($period->getDateInterval() != $clonedPeriod->getDateInterval()) {
+    echo "failure\n";
+}
+
+if ($interval->format('Y-m-d H:i:s') != $clonedInterval->format('Y-m-d H:i:s')) {
+    echo "failure\n";
+}
+
+echo 'success';
+?>
+--EXPECT--
+success