]> granicus.if.org Git - php/commitdiff
Fixed bug #60302: DateTime::createFromFormat should new static(), not new self()
authorDerick Rethans <github@derickrethans.nl>
Sun, 2 Aug 2020 23:41:31 +0000 (00:41 +0100)
committerDerick Rethans <github@derickrethans.nl>
Sun, 2 Aug 2020 23:43:41 +0000 (00:43 +0100)
Also fixes similar issues for DateTimeImmutable::createFromFormat,
DateTime::createFromImmmutable, DateTime::createFromInterface,
DateTimeImmutable::createFromMutable, and
DateTimeImmutable::createFromInterface.

12 files changed:
NEWS
ext/date/php_date.c
ext/date/tests/DateTimeImmutable_createFromInterface-001.phpt [moved from ext/date/tests/DateTimeImmutable_createFromInterface.phpt with 100% similarity]
ext/date/tests/DateTimeImmutable_createFromInterface-002.phpt [new file with mode: 0644]
ext/date/tests/DateTimeImmutable_createFromMutable-001.phpt [moved from ext/date/tests/DateTimeImmutable_createFromMutable.phpt with 100% similarity]
ext/date/tests/DateTimeImmutable_createFromMutable-002.phpt [new file with mode: 0644]
ext/date/tests/DateTime_createFromImmutable-001.phpt [moved from ext/date/tests/DateTime_createFromImmutable.phpt with 94% similarity]
ext/date/tests/DateTime_createFromImmutable-002.phpt [new file with mode: 0644]
ext/date/tests/DateTime_createFromInterface-001.phpt [moved from ext/date/tests/DateTime_createFromInterface.phpt with 100% similarity]
ext/date/tests/DateTime_createFromInterface-002.phpt [new file with mode: 0644]
ext/date/tests/bug60302-001.phpt [new file with mode: 0644]
ext/date/tests/bug60302-002.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 1dac12226ddc80c19ec2221cdb29ab605192fe72..d1ce1ff4a35a2585d8015b936c69ba10dc0d6257 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,10 @@ PHP                                                                        NEWS
   . Fixed bug #79897 (Promoted constructor params with attribs cause crash).
     (Deus Kane)
 
+- Date:
+  . Fixed bug #60302 (DateTime::createFromFormat should new static(), not new
+    self()). (Derick)
+
 - JIT:
   . Fixed bug #79864 (JIT segfault in Symfony OptionsResolver). (Dmitry)
   . Fixed bug #79888 (Incorrect execution with JIT enabled). (Dmitry)
index 46d50e283718fc441c97057684799ad36d760d2c..9839d768f9b422c4266126304c55581a153ca28a 100644 (file)
@@ -2292,7 +2292,7 @@ PHP_FUNCTION(date_create)
 }
 /* }}} */
 
-/* {{{ Returns new DateTime object */
+/* {{{ Returns new DateTimeImmutable object */
 PHP_FUNCTION(date_create_immutable)
 {
        zval           *timezone_object = NULL;
@@ -2327,7 +2327,7 @@ PHP_FUNCTION(date_create_from_format)
                Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone)
        ZEND_PARSE_PARAMETERS_END();
 
-       php_date_instantiate(date_ce_date, return_value);
+       php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, return_value);
        if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, 0)) {
                zval_ptr_dtor(return_value);
                RETURN_FALSE;
@@ -2349,7 +2349,7 @@ PHP_FUNCTION(date_create_immutable_from_format)
                Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone)
        ZEND_PARSE_PARAMETERS_END();
 
-       php_date_instantiate(date_ce_immutable, return_value);
+       php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, return_value);
        if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, 0)) {
                zval_ptr_dtor(return_value);
                RETURN_FALSE;
@@ -2408,7 +2408,7 @@ PHP_METHOD(DateTime, createFromImmutable)
                Z_PARAM_OBJECT_OF_CLASS(datetimeimmutable_object, date_ce_immutable)
        ZEND_PARSE_PARAMETERS_END();
 
-       php_date_instantiate(date_ce_date, return_value);
+       php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, return_value);
        old_obj = Z_PHPDATE_P(datetimeimmutable_object);
        new_obj = Z_PHPDATE_P(return_value);
 
@@ -2427,7 +2427,7 @@ PHP_METHOD(DateTime, createFromInterface)
                Z_PARAM_OBJECT_OF_CLASS(datetimeinterface_object, date_ce_interface)
        ZEND_PARSE_PARAMETERS_END();
 
-       php_date_instantiate(date_ce_date, return_value);
+       php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, return_value);
        old_obj = Z_PHPDATE_P(datetimeinterface_object);
        new_obj = Z_PHPDATE_P(return_value);
 
@@ -2446,7 +2446,7 @@ PHP_METHOD(DateTimeImmutable, createFromMutable)
                Z_PARAM_OBJECT_OF_CLASS(datetime_object, date_ce_date)
        ZEND_PARSE_PARAMETERS_END();
 
-       php_date_instantiate(date_ce_immutable, return_value);
+       php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, return_value);
        old_obj = Z_PHPDATE_P(datetime_object);
        new_obj = Z_PHPDATE_P(return_value);
 
@@ -2465,7 +2465,7 @@ PHP_METHOD(DateTimeImmutable, createFromInterface)
                Z_PARAM_OBJECT_OF_CLASS(datetimeinterface_object, date_ce_interface)
        ZEND_PARSE_PARAMETERS_END();
 
-       php_date_instantiate(date_ce_immutable, return_value);
+       php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, return_value);
        old_obj = Z_PHPDATE_P(datetimeinterface_object);
        new_obj = Z_PHPDATE_P(return_value);
 
diff --git a/ext/date/tests/DateTimeImmutable_createFromInterface-002.phpt b/ext/date/tests/DateTimeImmutable_createFromInterface-002.phpt
new file mode 100644 (file)
index 0000000..fcdc64c
--- /dev/null
@@ -0,0 +1,81 @@
+--TEST--
+Tests for DateTimeImmutable::createFromInterface inheritance
+--INI--
+date.timezone=Europe/London
+--FILE--
+<?php
+class MyDateTimeImmutable extends DateTimeImmutable {}
+
+$current = "2014-03-02 16:24:08";
+
+$i = MyDateTimeImmutable::createFromInterface( date_create( $current ) );
+var_dump( $i );
+
+$i = MyDateTimeImmutable::createFromInterface( date_create_immutable( $current ) );
+var_dump( $i );
+
+$current = "2019-12-16 15:06:46 CET";
+
+$i = MyDateTimeImmutable::createFromInterface( date_create( $current ) );
+var_dump( $i );
+
+$i = MyDateTimeImmutable::createFromInterface( date_create_immutable( $current ) );
+var_dump( $i );
+
+$current = "2019-12-16 15:08:20 +0100";
+
+$i = MyDateTimeImmutable::createFromInterface( date_create( $current ) );
+var_dump( $i );
+
+$i = MyDateTimeImmutable::createFromInterface( date_create_immutable( $current ) );
+var_dump( $i );
+?>
+--EXPECTF--
+object(MyDateTimeImmutable)#%d (3) {
+  ["date"]=>
+  string(26) "2014-03-02 16:24:08.000000"
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
+}
+object(MyDateTimeImmutable)#%d (3) {
+  ["date"]=>
+  string(26) "2014-03-02 16:24:08.000000"
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
+}
+object(MyDateTimeImmutable)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:06:46.000000"
+  ["timezone_type"]=>
+  int(2)
+  ["timezone"]=>
+  string(3) "CET"
+}
+object(MyDateTimeImmutable)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:06:46.000000"
+  ["timezone_type"]=>
+  int(2)
+  ["timezone"]=>
+  string(3) "CET"
+}
+object(MyDateTimeImmutable)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:08:20.000000"
+  ["timezone_type"]=>
+  int(1)
+  ["timezone"]=>
+  string(6) "+01:00"
+}
+object(MyDateTimeImmutable)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:08:20.000000"
+  ["timezone_type"]=>
+  int(1)
+  ["timezone"]=>
+  string(6) "+01:00"
+}
diff --git a/ext/date/tests/DateTimeImmutable_createFromMutable-002.phpt b/ext/date/tests/DateTimeImmutable_createFromMutable-002.phpt
new file mode 100644 (file)
index 0000000..ccbbe33
--- /dev/null
@@ -0,0 +1,29 @@
+--TEST--
+Tests for inherited DateTimeImmutable::createFromMutable
+--INI--
+date.timezone=Europe/London
+--FILE--
+<?php
+class MyDateTimeImmutable extends DateTimeImmutable {}
+
+$current = "2014-03-02 16:24:08";
+
+$i = MyDateTimeImmutable::createFromMutable( date_create( $current ) );
+var_dump( $i );
+
+try {
+    MyDateTimeImmutable::createFromMutable( date_create_immutable( $current ) );
+} catch (TypeError $e) {
+    echo $e->getMessage(), "\n";
+}
+?>
+--EXPECTF--
+object(MyDateTimeImmutable)#%d (3) {
+  ["date"]=>
+  string(26) "2014-03-02 16:24:08.000000"
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
+}
+DateTimeImmutable::createFromMutable(): Argument #1 ($object) must be of type DateTime, DateTimeImmutable given
similarity index 94%
rename from ext/date/tests/DateTime_createFromImmutable.phpt
rename to ext/date/tests/DateTime_createFromImmutable-001.phpt
index 59f61922141b0b93282238f8e469a0bcdcc0f546..031c8764847a4e23f1b675e0ade0a2ac8973fc0c 100644 (file)
@@ -1,5 +1,5 @@
 --TEST--
-Tests for DateTime::createFromImmutable.
+Tests for DateTime::createFromImmutable
 --INI--
 date.timezone=Europe/London
 --FILE--
diff --git a/ext/date/tests/DateTime_createFromImmutable-002.phpt b/ext/date/tests/DateTime_createFromImmutable-002.phpt
new file mode 100644 (file)
index 0000000..5b8c3a5
--- /dev/null
@@ -0,0 +1,35 @@
+--TEST--
+Tests for inherited DateTime::createFromImmutable
+--INI--
+date.timezone=Europe/London
+--FILE--
+<?php
+class MyDateTime extends DateTime {}
+
+$current = "2014-03-02 16:24:08";
+$i = date_create_immutable( $current );
+
+$m = MyDateTime::createFromImmutable( $i );
+var_dump( $m );
+
+$m->modify('+ 1 hour');
+
+var_dump( $i->format('Y-m-d H:i:s') === $current );
+
+try {
+    MyDateTime::createFromImmutable( date_create( $current ) );
+} catch (TypeError $e) {
+    echo $e->getMessage(), "\n";
+}
+?>
+--EXPECTF--
+object(MyDateTime)#%d (3) {
+  ["date"]=>
+  string(26) "2014-03-02 16:24:08.000000"
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
+}
+bool(true)
+DateTime::createFromImmutable(): Argument #1 ($object) must be of type DateTimeImmutable, DateTime given
diff --git a/ext/date/tests/DateTime_createFromInterface-002.phpt b/ext/date/tests/DateTime_createFromInterface-002.phpt
new file mode 100644 (file)
index 0000000..6e241a4
--- /dev/null
@@ -0,0 +1,81 @@
+--TEST--
+Tests for DateTime::createFromInterface with inheritance
+--INI--
+date.timezone=Europe/London
+--FILE--
+<?php
+class MyDateTime extends DateTime {}
+
+$current = "2014-03-02 16:24:08";
+
+$i = MyDateTime::createFromInterface( date_create( $current ) );
+var_dump( $i );
+
+$i = MyDateTime::createFromInterface( date_create_immutable( $current ) );
+var_dump( $i );
+
+$current = "2019-12-16 15:06:46 CET";
+
+$i = MyDateTime::createFromInterface( date_create( $current ) );
+var_dump( $i );
+
+$i = MyDateTime::createFromInterface( date_create_immutable( $current ) );
+var_dump( $i );
+
+$current = "2019-12-16 15:08:20 +0100";
+
+$i = MyDateTime::createFromInterface( date_create( $current ) );
+var_dump( $i );
+
+$i = MyDateTime::createFromInterface( date_create_immutable( $current ) );
+var_dump( $i );
+?>
+--EXPECTF--
+object(MyDateTime)#%d (3) {
+  ["date"]=>
+  string(26) "2014-03-02 16:24:08.000000"
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
+}
+object(MyDateTime)#%d (3) {
+  ["date"]=>
+  string(26) "2014-03-02 16:24:08.000000"
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
+}
+object(MyDateTime)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:06:46.000000"
+  ["timezone_type"]=>
+  int(2)
+  ["timezone"]=>
+  string(3) "CET"
+}
+object(MyDateTime)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:06:46.000000"
+  ["timezone_type"]=>
+  int(2)
+  ["timezone"]=>
+  string(3) "CET"
+}
+object(MyDateTime)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:08:20.000000"
+  ["timezone_type"]=>
+  int(1)
+  ["timezone"]=>
+  string(6) "+01:00"
+}
+object(MyDateTime)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:08:20.000000"
+  ["timezone_type"]=>
+  int(1)
+  ["timezone"]=>
+  string(6) "+01:00"
+}
diff --git a/ext/date/tests/bug60302-001.phpt b/ext/date/tests/bug60302-001.phpt
new file mode 100644 (file)
index 0000000..f86443e
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+Test for bug #60302: DateTime::createFromFormat should new static(), not new self()
+--FILE--
+<?php
+
+class MyDateTime extends DateTime { }
+
+$d = MyDateTime::createFromFormat('Y-m-d', '2011-01-01');
+
+echo get_class($d);
+?>
+--EXPECT--
+MyDateTime
diff --git a/ext/date/tests/bug60302-002.phpt b/ext/date/tests/bug60302-002.phpt
new file mode 100644 (file)
index 0000000..a4a3c4a
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+Test for bug #60302: DateTimeImmutable::createFromFormat should new static(), not new self()
+--FILE--
+<?php
+
+class MyDateTime extends DateTimeImmutable { }
+
+$d = MyDateTime::createFromFormat('Y-m-d', '2011-01-01');
+
+echo get_class($d);
+?>
+--EXPECT--
+MyDateTime