Skip to content

Commit

Permalink
Fix property_exists() and unset() for XMLReader (#16079)
Browse files Browse the repository at this point in the history
  • Loading branch information
kocsismate committed Sep 28, 2024
1 parent 16b272d commit f4f2fe5
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 0 deletions.
48 changes: 48 additions & 0 deletions ext/xmlreader/php_xmlreader.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,40 @@ zval *xmlreader_get_property_ptr_ptr(zend_object *object, zend_string *name, int
}
/* }}} */

static int xmlreader_has_property(zend_object *object, zend_string *name, int type, void **cache_slot)
{
xmlreader_object *obj = php_xmlreader_fetch_object(object);
xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name);

if (hnd != NULL) {
if (type == ZEND_PROPERTY_EXISTS) {
return 1;
}

zval rv;
if (xmlreader_property_reader(obj, hnd, &rv) == FAILURE) {
return 0;
}

bool result;

if (type == ZEND_PROPERTY_NOT_EMPTY) {
result = zend_is_true(&rv);
} else if (type == ZEND_PROPERTY_ISSET) {
result = (Z_TYPE(rv) != IS_NULL);
} else {
ZEND_UNREACHABLE();
}

zval_ptr_dtor(&rv);

return result;
}

return zend_std_has_property(object, name, type, cache_slot);
}


/* {{{ xmlreader_read_property */
zval *xmlreader_read_property(zend_object *object, zend_string *name, int type, void **cache_slot, zval *rv)
{
Expand Down Expand Up @@ -159,6 +193,18 @@ zval *xmlreader_write_property(zend_object *object, zend_string *name, zval *val
}
/* }}} */

void xmlreader_unset_property(zend_object *object, zend_string *name, void **cache_slot)
{
xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name);

if (hnd != NULL) {
zend_throw_error(NULL, "Cannot unset %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(name));
return;
}

zend_std_unset_property(object, name, cache_slot);
}

/* {{{ */
static zend_function *xmlreader_get_method(zend_object **obj, zend_string *name, const zval *key)
{
Expand Down Expand Up @@ -1293,8 +1339,10 @@ PHP_MINIT_FUNCTION(xmlreader)
memcpy(&xmlreader_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
xmlreader_object_handlers.offset = XtOffsetOf(xmlreader_object, std);
xmlreader_object_handlers.free_obj = xmlreader_objects_free_storage;
xmlreader_object_handlers.has_property = xmlreader_has_property;
xmlreader_object_handlers.read_property = xmlreader_read_property;
xmlreader_object_handlers.write_property = xmlreader_write_property;
xmlreader_object_handlers.unset_property = xmlreader_unset_property;
xmlreader_object_handlers.get_property_ptr_ptr = xmlreader_get_property_ptr_ptr;
xmlreader_object_handlers.get_method = xmlreader_get_method;
xmlreader_object_handlers.clone_obj = NULL;
Expand Down
46 changes: 46 additions & 0 deletions ext/xmlreader/tests/virtual_properties2.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
--TEST--
Virtual property existence tests
--EXTENSIONS--
xmlreader
--FILE--
<?php

$reader = new XMLReader();

var_dump(isset($reader->attributeCount));
var_dump(empty($reader->attributeCount));
var_dump(property_exists($reader, "attributeCount"));

var_dump(isset($reader->baseURI));
var_dump(empty($reader->baseURI));
var_dump(property_exists($reader, "baseURI"));

var_dump(isset($reader->depth));
var_dump(empty($reader->depth));
var_dump(property_exists($reader, "depth"));

var_dump(isset($reader->hasAttributes));
var_dump(empty($reader->hasAttributes));
var_dump(property_exists($reader, "hasAttributes"));

var_dump(isset($reader->hasValue));
var_dump(empty($reader->hasValue));
var_dump(property_exists($reader, "hasValue"));

?>
--EXPECT--
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
55 changes: 55 additions & 0 deletions ext/xmlreader/tests/virtual_properties3.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
--TEST--
Virtual property unset tests
--EXTENSIONS--
xmlreader
--FILE--
<?php

class MyXMLReader extends XMLReader
{
public int $x;
}

$reader = new MyXMLReader();

try {
unset($reader->attributeCount);
} catch (Error $e) {
echo $e->getMessage() . "\n";
}

try {
unset($reader->baseURI);
} catch (Error $e) {
echo $e->getMessage() . "\n";
}

try {
unset($reader->depth);
} catch (Error $e) {
echo $e->getMessage() . "\n";
}

try {
unset($reader->hasAttributes);
} catch (Error $e) {
echo $e->getMessage() . "\n";
}

try {
unset($reader->hasValue);
} catch (Error $e) {
echo $e->getMessage() . "\n";
}

unset($reader->x);
var_dump(isset($reader->x));

?>
--EXPECT--
Cannot unset MyXMLReader::$attributeCount
Cannot unset MyXMLReader::$baseURI
Cannot unset MyXMLReader::$depth
Cannot unset MyXMLReader::$hasAttributes
Cannot unset MyXMLReader::$hasValue
bool(false)

0 comments on commit f4f2fe5

Please sign in to comment.