Skip to content

Commit d2e7506

Browse files
committed
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.
1 parent c6c69b3 commit d2e7506

File tree

4 files changed

+81
-48
lines changed

4 files changed

+81
-48
lines changed

ext/date/php_date.c

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -667,12 +667,12 @@ static zend_object *date_object_clone_period(zval *this_ptr);
667667

668668
static int date_object_compare_date(zval *d1, zval *d2);
669669
static HashTable *date_object_get_gc(zval *object, zval **table, int *n);
670-
static HashTable *date_object_get_properties(zval *object);
670+
static HashTable *date_object_get_properties_for(zval *object, zend_prop_purpose purpose);
671671
static HashTable *date_object_get_gc_interval(zval *object, zval **table, int *n);
672672
static HashTable *date_object_get_properties_interval(zval *object);
673673
static HashTable *date_object_get_gc_period(zval *object, zval **table, int *n);
674674
static HashTable *date_object_get_properties_period(zval *object);
675-
static HashTable *date_object_get_properties_timezone(zval *object);
675+
static HashTable *date_object_get_properties_for_timezone(zval *object, zend_prop_purpose purpose);
676676
static HashTable *date_object_get_gc_timezone(zval *object, zval **table, int *n);
677677
static HashTable *date_object_get_debug_info_timezone(zval *object, int *is_temp);
678678
static void php_timezone_to_string(php_timezone_obj *tzobj, zval *zv);
@@ -2123,7 +2123,7 @@ static void date_register_classes(void) /* {{{ */
21232123
date_object_handlers_date.free_obj = date_object_free_storage_date;
21242124
date_object_handlers_date.clone_obj = date_object_clone_date;
21252125
date_object_handlers_date.compare_objects = date_object_compare_date;
2126-
date_object_handlers_date.get_properties = date_object_get_properties;
2126+
date_object_handlers_date.get_properties_for = date_object_get_properties_for;
21272127
date_object_handlers_date.get_gc = date_object_get_gc;
21282128
zend_class_implements(date_ce_date, 1, date_ce_interface);
21292129

@@ -2133,7 +2133,7 @@ static void date_register_classes(void) /* {{{ */
21332133
memcpy(&date_object_handlers_immutable, &std_object_handlers, sizeof(zend_object_handlers));
21342134
date_object_handlers_immutable.clone_obj = date_object_clone_date;
21352135
date_object_handlers_immutable.compare_objects = date_object_compare_date;
2136-
date_object_handlers_immutable.get_properties = date_object_get_properties;
2136+
date_object_handlers_immutable.get_properties_for = date_object_get_properties_for;
21372137
date_object_handlers_immutable.get_gc = date_object_get_gc;
21382138
zend_class_implements(date_ce_immutable, 1, date_ce_interface);
21392139

@@ -2144,7 +2144,7 @@ static void date_register_classes(void) /* {{{ */
21442144
date_object_handlers_timezone.offset = XtOffsetOf(php_timezone_obj, std);
21452145
date_object_handlers_timezone.free_obj = date_object_free_storage_timezone;
21462146
date_object_handlers_timezone.clone_obj = date_object_clone_timezone;
2147-
date_object_handlers_timezone.get_properties = date_object_get_properties_timezone;
2147+
date_object_handlers_timezone.get_properties_for = date_object_get_properties_for_timezone;
21482148
date_object_handlers_timezone.get_gc = date_object_get_gc_timezone;
21492149
date_object_handlers_timezone.get_debug_info = date_object_get_debug_info_timezone;
21502150

@@ -2273,17 +2273,23 @@ static HashTable *date_object_get_gc_timezone(zval *object, zval **table, int *n
22732273
return zend_std_get_properties(object);
22742274
} /* }}} */
22752275

2276-
static HashTable *date_object_get_properties(zval *object) /* {{{ */
2276+
static HashTable *date_object_get_properties_for(zval *object, zend_prop_purpose purpose) /* {{{ */
22772277
{
22782278
HashTable *props;
22792279
zval zv;
2280-
php_date_obj *dateobj;
2280+
php_date_obj *dateobj;
22812281

2282+
switch (purpose) {
2283+
case ZEND_PROP_PURPOSE_DEBUG:
2284+
case ZEND_PROP_PURPOSE_SERIALIZE:
2285+
case ZEND_PROP_PURPOSE_VAR_EXPORT:
2286+
break;
2287+
default:
2288+
return zend_std_get_properties_for(object, purpose);
2289+
}
22822290

22832291
dateobj = Z_PHPDATE_P(object);
2284-
2285-
props = zend_std_get_properties(object);
2286-
2292+
props = zend_array_dup(zend_std_get_properties(object));
22872293
if (!dateobj->time) {
22882294
return props;
22892295
}
@@ -2387,16 +2393,23 @@ static void php_timezone_to_string(php_timezone_obj *tzobj, zval *zv)
23872393
}
23882394
}
23892395

2390-
static HashTable *date_object_get_properties_timezone(zval *object) /* {{{ */
2396+
static HashTable *date_object_get_properties_for_timezone(zval *object, zend_prop_purpose purpose) /* {{{ */
23912397
{
23922398
HashTable *props;
23932399
zval zv;
2394-
php_timezone_obj *tzobj;
2395-
2396-
tzobj = Z_PHPTIMEZONE_P(object);
2400+
php_timezone_obj *tzobj;
23972401

2398-
props = zend_std_get_properties(object);
2402+
switch (purpose) {
2403+
case ZEND_PROP_PURPOSE_DEBUG:
2404+
case ZEND_PROP_PURPOSE_SERIALIZE:
2405+
case ZEND_PROP_PURPOSE_VAR_EXPORT:
2406+
break;
2407+
default:
2408+
return zend_std_get_properties_for(object, purpose);
2409+
}
23992410

2411+
tzobj = Z_PHPTIMEZONE_P(object);
2412+
props = zend_array_dup(zend_std_get_properties(object));
24002413
if (!tzobj->initialized) {
24012414
return props;
24022415
}
@@ -2468,12 +2481,10 @@ static HashTable *date_object_get_properties_interval(zval *object) /* {{{ */
24682481
{
24692482
HashTable *props;
24702483
zval zv;
2471-
php_interval_obj *intervalobj;
2484+
php_interval_obj *intervalobj;
24722485

24732486
intervalobj = Z_PHPINTERVAL_P(object);
2474-
24752487
props = zend_std_get_properties(object);
2476-
24772488
if (!intervalobj->initialized) {
24782489
return props;
24792490
}
@@ -5094,9 +5105,7 @@ static HashTable *date_object_get_properties_period(zval *object) /* {{{ */
50945105
php_period_obj *period_obj;
50955106

50965107
period_obj = Z_PHPPERIOD_P(object);
5097-
50985108
props = zend_std_get_properties(object);
5099-
51005109
if (!period_obj->start) {
51015110
return props;
51025111
}

ext/date/tests/DateTime_clone_basic3.phpt

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,40 +41,34 @@ object(DateTime)#%d (3) {
4141

4242
-- Add some properties --
4343
object(DateTime)#%d (5) {
44-
["date"]=>
45-
string(26) "2009-02-03 12:34:41.000000"
46-
["timezone_type"]=>
47-
int(2)
48-
["timezone"]=>
49-
string(3) "GMT"
5044
["property1"]=>
5145
int(99)
5246
["property2"]=>
5347
string(5) "Hello"
54-
}
55-
56-
-- clone it --
57-
object(DateTime)#%d (5) {
5848
["date"]=>
5949
string(26) "2009-02-03 12:34:41.000000"
6050
["timezone_type"]=>
6151
int(2)
6252
["timezone"]=>
6353
string(3) "GMT"
54+
}
55+
56+
-- clone it --
57+
object(DateTime)#%d (5) {
6458
["property1"]=>
6559
int(99)
6660
["property2"]=>
6761
string(5) "Hello"
68-
}
69-
70-
-- Add some more properties --
71-
object(DateTime)#%d (7) {
7262
["date"]=>
7363
string(26) "2009-02-03 12:34:41.000000"
7464
["timezone_type"]=>
7565
int(2)
7666
["timezone"]=>
7767
string(3) "GMT"
68+
}
69+
70+
-- Add some more properties --
71+
object(DateTime)#%d (7) {
7872
["property1"]=>
7973
int(99)
8074
["property2"]=>
@@ -83,16 +77,16 @@ object(DateTime)#%d (7) {
8377
bool(true)
8478
["property4"]=>
8579
float(10.5)
86-
}
87-
88-
-- clone it --
89-
object(DateTime)#%d (7) {
9080
["date"]=>
9181
string(26) "2009-02-03 12:34:41.000000"
9282
["timezone_type"]=>
9383
int(2)
9484
["timezone"]=>
9585
string(3) "GMT"
86+
}
87+
88+
-- clone it --
89+
object(DateTime)#%d (7) {
9690
["property1"]=>
9791
int(99)
9892
["property2"]=>
@@ -101,5 +95,11 @@ object(DateTime)#%d (7) {
10195
bool(true)
10296
["property4"]=>
10397
float(10.5)
98+
["date"]=>
99+
string(26) "2009-02-03 12:34:41.000000"
100+
["timezone_type"]=>
101+
int(2)
102+
["timezone"]=>
103+
string(3) "GMT"
104104
}
105105
===DONE===

ext/date/tests/bug52113.phpt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ $p = new DatePeriod($start, $diff_un, 2);
3232
var_dump($unser, $p);
3333

3434
?>
35-
--EXPECT--
36-
object(DateInterval)#3 (16) {
35+
--EXPECTF--
36+
object(DateInterval)#%d (16) {
3737
["y"]=>
3838
int(0)
3939
["m"]=>
@@ -85,7 +85,7 @@ DateInterval::__set_state(array(
8585
'special_amount' => 0,
8686
'have_weekday_relative' => 0,
8787
'have_special_relative' => 0,
88-
))object(DateInterval)#5 (16) {
88+
))object(DateInterval)#%d (16) {
8989
["y"]=>
9090
int(0)
9191
["m"]=>
@@ -119,9 +119,9 @@ DateInterval::__set_state(array(
119119
["have_special_relative"]=>
120120
int(0)
121121
}
122-
object(DatePeriod)#6 (6) {
122+
object(DatePeriod)#%d (6) {
123123
["start"]=>
124-
object(DateTime)#4 (3) {
124+
object(DateTime)#%d (3) {
125125
["date"]=>
126126
string(26) "2003-01-02 08:00:00.000000"
127127
["timezone_type"]=>
@@ -134,7 +134,7 @@ object(DatePeriod)#6 (6) {
134134
["end"]=>
135135
NULL
136136
["interval"]=>
137-
object(DateInterval)#7 (16) {
137+
object(DateInterval)#%d (16) {
138138
["y"]=>
139139
int(0)
140140
["m"]=>
@@ -173,7 +173,7 @@ object(DatePeriod)#6 (6) {
173173
["include_start_date"]=>
174174
bool(true)
175175
}
176-
object(DateInterval)#8 (16) {
176+
object(DateInterval)#%d (16) {
177177
["y"]=>
178178
int(7)
179179
["m"]=>
@@ -207,9 +207,9 @@ object(DateInterval)#8 (16) {
207207
["have_special_relative"]=>
208208
int(0)
209209
}
210-
object(DatePeriod)#9 (6) {
210+
object(DatePeriod)#%d (6) {
211211
["start"]=>
212-
object(DateTime)#6 (3) {
212+
object(DateTime)#%d (3) {
213213
["date"]=>
214214
string(26) "2003-01-02 08:00:00.000000"
215215
["timezone_type"]=>
@@ -222,7 +222,7 @@ object(DatePeriod)#9 (6) {
222222
["end"]=>
223223
NULL
224224
["interval"]=>
225-
object(DateInterval)#7 (16) {
225+
object(DateInterval)#%d (16) {
226226
["y"]=>
227227
int(0)
228228
["m"]=>

ext/date/tests/bug75232.phpt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
Bug #75232: print_r of DateTime creating side-effect
3+
--FILE--
4+
<?php
5+
6+
$d1 = DateTime::createFromFormat("Ymd\THis\Z", '20170920T091600Z');
7+
echo $d1->date, "\n";
8+
9+
$d2 = DateTime::createFromFormat("Ymd\THis\Z", '20170920T091600Z');
10+
print_r($d2);
11+
echo $d2->date, "\n";
12+
13+
?>
14+
--EXPECTF--
15+
Notice: Undefined property: DateTime::$date in %s on line %d
16+
17+
DateTime Object
18+
(
19+
[date] => 2017-09-20 09:16:00.000000
20+
[timezone_type] => 3
21+
[timezone] => UTC
22+
)
23+
24+
Notice: Undefined property: DateTime::$date in %s on line %d

0 commit comments

Comments
 (0)