Skip to content

Commit f4f2fe5

Browse files
authored
Fix property_exists() and unset() for XMLReader (#16079)
1 parent 16b272d commit f4f2fe5

File tree

3 files changed

+149
-0
lines changed

3 files changed

+149
-0
lines changed

ext/xmlreader/php_xmlreader.c

+48
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,40 @@ zval *xmlreader_get_property_ptr_ptr(zend_object *object, zend_string *name, int
123123
}
124124
/* }}} */
125125

126+
static int xmlreader_has_property(zend_object *object, zend_string *name, int type, void **cache_slot)
127+
{
128+
xmlreader_object *obj = php_xmlreader_fetch_object(object);
129+
xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name);
130+
131+
if (hnd != NULL) {
132+
if (type == ZEND_PROPERTY_EXISTS) {
133+
return 1;
134+
}
135+
136+
zval rv;
137+
if (xmlreader_property_reader(obj, hnd, &rv) == FAILURE) {
138+
return 0;
139+
}
140+
141+
bool result;
142+
143+
if (type == ZEND_PROPERTY_NOT_EMPTY) {
144+
result = zend_is_true(&rv);
145+
} else if (type == ZEND_PROPERTY_ISSET) {
146+
result = (Z_TYPE(rv) != IS_NULL);
147+
} else {
148+
ZEND_UNREACHABLE();
149+
}
150+
151+
zval_ptr_dtor(&rv);
152+
153+
return result;
154+
}
155+
156+
return zend_std_has_property(object, name, type, cache_slot);
157+
}
158+
159+
126160
/* {{{ xmlreader_read_property */
127161
zval *xmlreader_read_property(zend_object *object, zend_string *name, int type, void **cache_slot, zval *rv)
128162
{
@@ -159,6 +193,18 @@ zval *xmlreader_write_property(zend_object *object, zend_string *name, zval *val
159193
}
160194
/* }}} */
161195

196+
void xmlreader_unset_property(zend_object *object, zend_string *name, void **cache_slot)
197+
{
198+
xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name);
199+
200+
if (hnd != NULL) {
201+
zend_throw_error(NULL, "Cannot unset %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(name));
202+
return;
203+
}
204+
205+
zend_std_unset_property(object, name, cache_slot);
206+
}
207+
162208
/* {{{ */
163209
static zend_function *xmlreader_get_method(zend_object **obj, zend_string *name, const zval *key)
164210
{
@@ -1293,8 +1339,10 @@ PHP_MINIT_FUNCTION(xmlreader)
12931339
memcpy(&xmlreader_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
12941340
xmlreader_object_handlers.offset = XtOffsetOf(xmlreader_object, std);
12951341
xmlreader_object_handlers.free_obj = xmlreader_objects_free_storage;
1342+
xmlreader_object_handlers.has_property = xmlreader_has_property;
12961343
xmlreader_object_handlers.read_property = xmlreader_read_property;
12971344
xmlreader_object_handlers.write_property = xmlreader_write_property;
1345+
xmlreader_object_handlers.unset_property = xmlreader_unset_property;
12981346
xmlreader_object_handlers.get_property_ptr_ptr = xmlreader_get_property_ptr_ptr;
12991347
xmlreader_object_handlers.get_method = xmlreader_get_method;
13001348
xmlreader_object_handlers.clone_obj = NULL;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--TEST--
2+
Virtual property existence tests
3+
--EXTENSIONS--
4+
xmlreader
5+
--FILE--
6+
<?php
7+
8+
$reader = new XMLReader();
9+
10+
var_dump(isset($reader->attributeCount));
11+
var_dump(empty($reader->attributeCount));
12+
var_dump(property_exists($reader, "attributeCount"));
13+
14+
var_dump(isset($reader->baseURI));
15+
var_dump(empty($reader->baseURI));
16+
var_dump(property_exists($reader, "baseURI"));
17+
18+
var_dump(isset($reader->depth));
19+
var_dump(empty($reader->depth));
20+
var_dump(property_exists($reader, "depth"));
21+
22+
var_dump(isset($reader->hasAttributes));
23+
var_dump(empty($reader->hasAttributes));
24+
var_dump(property_exists($reader, "hasAttributes"));
25+
26+
var_dump(isset($reader->hasValue));
27+
var_dump(empty($reader->hasValue));
28+
var_dump(property_exists($reader, "hasValue"));
29+
30+
?>
31+
--EXPECT--
32+
bool(true)
33+
bool(true)
34+
bool(true)
35+
bool(true)
36+
bool(true)
37+
bool(true)
38+
bool(true)
39+
bool(true)
40+
bool(true)
41+
bool(true)
42+
bool(true)
43+
bool(true)
44+
bool(true)
45+
bool(true)
46+
bool(true)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
--TEST--
2+
Virtual property unset tests
3+
--EXTENSIONS--
4+
xmlreader
5+
--FILE--
6+
<?php
7+
8+
class MyXMLReader extends XMLReader
9+
{
10+
public int $x;
11+
}
12+
13+
$reader = new MyXMLReader();
14+
15+
try {
16+
unset($reader->attributeCount);
17+
} catch (Error $e) {
18+
echo $e->getMessage() . "\n";
19+
}
20+
21+
try {
22+
unset($reader->baseURI);
23+
} catch (Error $e) {
24+
echo $e->getMessage() . "\n";
25+
}
26+
27+
try {
28+
unset($reader->depth);
29+
} catch (Error $e) {
30+
echo $e->getMessage() . "\n";
31+
}
32+
33+
try {
34+
unset($reader->hasAttributes);
35+
} catch (Error $e) {
36+
echo $e->getMessage() . "\n";
37+
}
38+
39+
try {
40+
unset($reader->hasValue);
41+
} catch (Error $e) {
42+
echo $e->getMessage() . "\n";
43+
}
44+
45+
unset($reader->x);
46+
var_dump(isset($reader->x));
47+
48+
?>
49+
--EXPECT--
50+
Cannot unset MyXMLReader::$attributeCount
51+
Cannot unset MyXMLReader::$baseURI
52+
Cannot unset MyXMLReader::$depth
53+
Cannot unset MyXMLReader::$hasAttributes
54+
Cannot unset MyXMLReader::$hasValue
55+
bool(false)

0 commit comments

Comments
 (0)