Migrate ext/date to get_properties_for where appropriate

This resolves the long-standing issue where var_dump
a DateTime (etc) object makes a number of additional properties
accessible, which may also change other behaviors as a side-effect.
This commit is contained in:
Nikita Popov 2018-10-04 16:51:52 +02:00
parent 7ec8087f80
commit 1270e5008a
4 changed files with 85 additions and 50 deletions

View File

@ -667,12 +667,12 @@ static zend_object *date_object_clone_period(zval *this_ptr);
static int date_object_compare_date(zval *d1, zval *d2);
static HashTable *date_object_get_gc(zval *object, zval **table, int *n);
static HashTable *date_object_get_properties(zval *object);
static HashTable *date_object_get_properties_for(zval *object, zend_prop_purpose purpose);
static HashTable *date_object_get_gc_interval(zval *object, zval **table, int *n);
static HashTable *date_object_get_properties_interval(zval *object);
static HashTable *date_object_get_gc_period(zval *object, zval **table, int *n);
static HashTable *date_object_get_properties_period(zval *object);
static HashTable *date_object_get_properties_timezone(zval *object);
static HashTable *date_object_get_properties_for_timezone(zval *object, zend_prop_purpose purpose);
static HashTable *date_object_get_gc_timezone(zval *object, zval **table, int *n);
static HashTable *date_object_get_debug_info_timezone(zval *object, int *is_temp);
static void php_timezone_to_string(php_timezone_obj *tzobj, zval *zv);
@ -2123,7 +2123,7 @@ static void date_register_classes(void) /* {{{ */
date_object_handlers_date.free_obj = date_object_free_storage_date;
date_object_handlers_date.clone_obj = date_object_clone_date;
date_object_handlers_date.compare_objects = date_object_compare_date;
date_object_handlers_date.get_properties = date_object_get_properties;
date_object_handlers_date.get_properties_for = date_object_get_properties_for;
date_object_handlers_date.get_gc = date_object_get_gc;
zend_class_implements(date_ce_date, 1, date_ce_interface);
@ -2133,7 +2133,7 @@ static void date_register_classes(void) /* {{{ */
memcpy(&date_object_handlers_immutable, &std_object_handlers, sizeof(zend_object_handlers));
date_object_handlers_immutable.clone_obj = date_object_clone_date;
date_object_handlers_immutable.compare_objects = date_object_compare_date;
date_object_handlers_immutable.get_properties = date_object_get_properties;
date_object_handlers_immutable.get_properties_for = date_object_get_properties_for;
date_object_handlers_immutable.get_gc = date_object_get_gc;
zend_class_implements(date_ce_immutable, 1, date_ce_interface);
@ -2144,7 +2144,7 @@ static void date_register_classes(void) /* {{{ */
date_object_handlers_timezone.offset = XtOffsetOf(php_timezone_obj, std);
date_object_handlers_timezone.free_obj = date_object_free_storage_timezone;
date_object_handlers_timezone.clone_obj = date_object_clone_timezone;
date_object_handlers_timezone.get_properties = date_object_get_properties_timezone;
date_object_handlers_timezone.get_properties_for = date_object_get_properties_for_timezone;
date_object_handlers_timezone.get_gc = date_object_get_gc_timezone;
date_object_handlers_timezone.get_debug_info = date_object_get_debug_info_timezone;
@ -2273,17 +2273,24 @@ static HashTable *date_object_get_gc_timezone(zval *object, zval **table, int *n
return zend_std_get_properties(object);
} /* }}} */
static HashTable *date_object_get_properties(zval *object) /* {{{ */
static HashTable *date_object_get_properties_for(zval *object, zend_prop_purpose purpose) /* {{{ */
{
HashTable *props;
zval zv;
php_date_obj *dateobj;
php_date_obj *dateobj;
switch (purpose) {
case ZEND_PROP_PURPOSE_DEBUG:
case ZEND_PROP_PURPOSE_SERIALIZE:
case ZEND_PROP_PURPOSE_VAR_EXPORT:
case ZEND_PROP_PURPOSE_JSON:
break;
default:
return zend_std_get_properties_for(object, purpose);
}
dateobj = Z_PHPDATE_P(object);
props = zend_std_get_properties(object);
props = zend_array_dup(zend_std_get_properties(object));
if (!dateobj->time) {
return props;
}
@ -2387,16 +2394,24 @@ static void php_timezone_to_string(php_timezone_obj *tzobj, zval *zv)
}
}
static HashTable *date_object_get_properties_timezone(zval *object) /* {{{ */
static HashTable *date_object_get_properties_for_timezone(zval *object, zend_prop_purpose purpose) /* {{{ */
{
HashTable *props;
zval zv;
php_timezone_obj *tzobj;
php_timezone_obj *tzobj;
switch (purpose) {
case ZEND_PROP_PURPOSE_DEBUG:
case ZEND_PROP_PURPOSE_SERIALIZE:
case ZEND_PROP_PURPOSE_VAR_EXPORT:
case ZEND_PROP_PURPOSE_JSON:
break;
default:
return zend_std_get_properties_for(object, purpose);
}
tzobj = Z_PHPTIMEZONE_P(object);
props = zend_std_get_properties(object);
props = zend_array_dup(zend_std_get_properties(object));
if (!tzobj->initialized) {
return props;
}
@ -2468,12 +2483,10 @@ static HashTable *date_object_get_properties_interval(zval *object) /* {{{ */
{
HashTable *props;
zval zv;
php_interval_obj *intervalobj;
php_interval_obj *intervalobj;
intervalobj = Z_PHPINTERVAL_P(object);
props = zend_std_get_properties(object);
if (!intervalobj->initialized) {
return props;
}
@ -5094,9 +5107,7 @@ static HashTable *date_object_get_properties_period(zval *object) /* {{{ */
php_period_obj *period_obj;
period_obj = Z_PHPPERIOD_P(object);
props = zend_std_get_properties(object);
if (!period_obj->start) {
return props;
}

View File

@ -41,40 +41,34 @@ object(DateTime)#%d (3) {
-- Add some properties --
object(DateTime)#%d (5) {
["property1"]=>
int(99)
["property2"]=>
string(5) "Hello"
["date"]=>
string(26) "2009-02-03 12:34:41.000000"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "GMT"
["property1"]=>
int(99)
["property2"]=>
string(5) "Hello"
}
-- clone it --
object(DateTime)#%d (5) {
["property1"]=>
int(99)
["property2"]=>
string(5) "Hello"
["date"]=>
string(26) "2009-02-03 12:34:41.000000"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "GMT"
["property1"]=>
int(99)
["property2"]=>
string(5) "Hello"
}
-- Add some more properties --
object(DateTime)#%d (7) {
["date"]=>
string(26) "2009-02-03 12:34:41.000000"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "GMT"
["property1"]=>
int(99)
["property2"]=>
@ -83,16 +77,16 @@ object(DateTime)#%d (7) {
bool(true)
["property4"]=>
float(10.5)
["date"]=>
string(26) "2009-02-03 12:34:41.000000"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "GMT"
}
-- clone it --
object(DateTime)#%d (7) {
["date"]=>
string(26) "2009-02-03 12:34:41.000000"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "GMT"
["property1"]=>
int(99)
["property2"]=>
@ -101,5 +95,11 @@ object(DateTime)#%d (7) {
bool(true)
["property4"]=>
float(10.5)
["date"]=>
string(26) "2009-02-03 12:34:41.000000"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "GMT"
}
===DONE===

View File

@ -32,8 +32,8 @@ $p = new DatePeriod($start, $diff_un, 2);
var_dump($unser, $p);
?>
--EXPECT--
object(DateInterval)#3 (16) {
--EXPECTF--
object(DateInterval)#%d (16) {
["y"]=>
int(0)
["m"]=>
@ -85,7 +85,7 @@ DateInterval::__set_state(array(
'special_amount' => 0,
'have_weekday_relative' => 0,
'have_special_relative' => 0,
))object(DateInterval)#5 (16) {
))object(DateInterval)#%d (16) {
["y"]=>
int(0)
["m"]=>
@ -119,9 +119,9 @@ DateInterval::__set_state(array(
["have_special_relative"]=>
int(0)
}
object(DatePeriod)#6 (6) {
object(DatePeriod)#%d (6) {
["start"]=>
object(DateTime)#4 (3) {
object(DateTime)#%d (3) {
["date"]=>
string(26) "2003-01-02 08:00:00.000000"
["timezone_type"]=>
@ -134,7 +134,7 @@ object(DatePeriod)#6 (6) {
["end"]=>
NULL
["interval"]=>
object(DateInterval)#7 (16) {
object(DateInterval)#%d (16) {
["y"]=>
int(0)
["m"]=>
@ -173,7 +173,7 @@ object(DatePeriod)#6 (6) {
["include_start_date"]=>
bool(true)
}
object(DateInterval)#8 (16) {
object(DateInterval)#%d (16) {
["y"]=>
int(7)
["m"]=>
@ -207,9 +207,9 @@ object(DateInterval)#8 (16) {
["have_special_relative"]=>
int(0)
}
object(DatePeriod)#9 (6) {
object(DatePeriod)#%d (6) {
["start"]=>
object(DateTime)#6 (3) {
object(DateTime)#%d (3) {
["date"]=>
string(26) "2003-01-02 08:00:00.000000"
["timezone_type"]=>
@ -222,7 +222,7 @@ object(DatePeriod)#9 (6) {
["end"]=>
NULL
["interval"]=>
object(DateInterval)#7 (16) {
object(DateInterval)#%d (16) {
["y"]=>
int(0)
["m"]=>

View File

@ -0,0 +1,24 @@
--TEST--
Bug #75232: print_r of DateTime creating side-effect
--FILE--
<?php
$d1 = DateTime::createFromFormat("Ymd\THis\Z", '20170920T091600Z');
echo $d1->date, "\n";
$d2 = DateTime::createFromFormat("Ymd\THis\Z", '20170920T091600Z');
print_r($d2);
echo $d2->date, "\n";
?>
--EXPECTF--
Notice: Undefined property: DateTime::$date in %s on line %d
DateTime Object
(
[date] => 2017-09-20 09:16:00.000000
[timezone_type] => 3
[timezone] => UTC
)
Notice: Undefined property: DateTime::$date in %s on line %d