Skip to content

Commit ba08538

Browse files
committed
Fix GH-18304: Changing the properties of a DateInterval through dynamic properties triggers a SegFault
For dynamic fetches the cache_slot will be NULL, so we have to check for that when resetting the cache. For zip and xmlreader this couldn't easily be tested because of a lack of writable properties. Closes GH-18307.
1 parent 29f96fb commit ba08538

File tree

14 files changed

+123
-11
lines changed

14 files changed

+123
-11
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.3.21
44

5+
- Core:
6+
. Fixed bug GH-18304 (Changing the properties of a DateInterval through
7+
dynamic properties triggers a SegFault). (nielsdos)
8+
59
- GD:
610
. Fixed imagecrop() overflow with rect argument with x/width y/heigh usage
711
in gdImageCrop(). (David Carlier)

ext/date/php_date.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4399,7 +4399,9 @@ static zval *date_interval_get_property_ptr_ptr(zend_object *object, zend_string
43994399
zend_string_equals_literal(name, "days") ||
44004400
zend_string_equals_literal(name, "invert") ) {
44014401
/* Fallback to read_property. */
4402-
cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL;
4402+
if (cache_slot) {
4403+
cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL;
4404+
}
44034405
ret = NULL;
44044406
} else {
44054407
ret = zend_std_get_property_ptr_ptr(object, name, type, cache_slot);

ext/date/tests/gh18304.phpt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
GH-18304 (Changing the properties of a DateInterval through dynamic properties triggers a SegFault)
3+
--CREDITS--
4+
orose-assetgo
5+
--FILE--
6+
<?php
7+
$di = new \DateInterval('P0Y');
8+
$field = 'd';
9+
$i = 1;
10+
$di->$field += $i;
11+
var_dump($di);
12+
?>
13+
--EXPECT--
14+
object(DateInterval)#1 (10) {
15+
["y"]=>
16+
int(0)
17+
["m"]=>
18+
int(0)
19+
["d"]=>
20+
int(1)
21+
["h"]=>
22+
int(0)
23+
["i"]=>
24+
int(0)
25+
["s"]=>
26+
int(0)
27+
["f"]=>
28+
float(0)
29+
["invert"]=>
30+
int(0)
31+
["days"]=>
32+
bool(false)
33+
["from_string"]=>
34+
bool(false)
35+
}

ext/dom/php_dom.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,9 @@ static zval *dom_get_property_ptr_ptr(zend_object *object, zend_string *name, in
303303
return zend_std_get_property_ptr_ptr(object, name, type, cache_slot);
304304
}
305305

306-
cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL;
306+
if (cache_slot) {
307+
cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL;
308+
}
307309
return NULL;
308310
}
309311

ext/dom/tests/gh18304.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
GH-18304 (Changing the properties of a DateInterval through dynamic properties triggers a SegFault)
3+
--CREDITS--
4+
orose-assetgo
5+
--EXTENSIONS--
6+
dom
7+
--FILE--
8+
<?php
9+
$text = new \DOMText();
10+
$field = 'textContent';
11+
$text->$field .= 'hello';
12+
var_dump($text->$field);
13+
?>
14+
--EXPECT--
15+
string(5) "hello"

ext/pdo/pdo_stmt.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2493,9 +2493,10 @@ static zval *pdo_row_get_property_ptr_ptr(zend_object *object, zend_string *name
24932493
ZEND_IGNORE_VALUE(object);
24942494
ZEND_IGNORE_VALUE(name);
24952495
ZEND_IGNORE_VALUE(type);
2496-
ZEND_IGNORE_VALUE(cache_slot);
24972496

2498-
cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL;
2497+
if (cache_slot) {
2498+
cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL;
2499+
}
24992500
return NULL;
25002501
}
25012502

ext/simplexml/simplexml.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,9 @@ static zval *sxe_property_get_adr(zend_object *object, zend_string *zname, int f
635635
SXE_ITER type;
636636
zval member;
637637

638-
cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL;
638+
if (cache_slot) {
639+
cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL;
640+
}
639641

640642
sxe = php_sxe_fetch_object(object);
641643
GET_NODE(sxe, node);

ext/simplexml/tests/gh18304.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
GH-18304 (Changing the properties of a DateInterval through dynamic properties triggers a SegFault)
3+
--CREDITS--
4+
orose-assetgo
5+
--EXTENSIONS--
6+
simplexml
7+
--FILE--
8+
<?php
9+
$sxe = simplexml_load_string('<root><abc/></root>');
10+
$field = 'abc';
11+
$sxe->$field .= 'hello';
12+
var_dump($sxe->$field);
13+
?>
14+
--EXPECT--
15+
object(SimpleXMLElement)#3 (1) {
16+
[0]=>
17+
string(5) "hello"
18+
}

ext/snmp/snmp.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1861,7 +1861,9 @@ static zval *php_snmp_get_property_ptr_ptr(zend_object *object, zend_string *nam
18611861
return zend_std_get_property_ptr_ptr(object, name, type, cache_slot);
18621862
}
18631863

1864-
cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL;
1864+
if (cache_slot) {
1865+
cache_slot[0] = cache_slot[1] = cache_slot[2] = NULL;
1866+
}
18651867
return NULL;
18661868
}
18671869

ext/snmp/tests/gh18304.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
GH-18304 (Changing the properties of a DateInterval through dynamic properties triggers a SegFault)
3+
--CREDITS--
4+
orose-assetgo
5+
--EXTENSIONS--
6+
snmp
7+
--FILE--
8+
<?php
9+
$snmp = new SNMP(1, '127.0.0.1', 'community');
10+
$field = 'max_oids';
11+
$snmp->$field++;
12+
var_dump($snmp->$field);
13+
?>
14+
--EXPECT--
15+
int(1)

0 commit comments

Comments
 (0)