Skip to content

Commit 7da2151

Browse files
committed
Declare typed properties in ext/dom
Closes GH-7013
1 parent f486501 commit 7da2151

8 files changed

+164
-158
lines changed

ext/dom/php_dom.c

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -265,47 +265,28 @@ PHP_DOM_EXPORT dom_object *php_dom_object_get_data(xmlNodePtr obj)
265265
}
266266
/* }}} end php_dom_object_get_data */
267267

268-
/* {{{ dom_read_na */
269-
static int dom_read_na(dom_object *obj, zval *retval)
270-
{
271-
zend_throw_error(NULL, "Cannot read property");
272-
return FAILURE;
273-
}
274-
/* }}} */
275-
276-
/* {{{ dom_write_na */
277-
static int dom_write_na(dom_object *obj, zval *newval)
278-
{
279-
zend_throw_error(NULL, "Cannot write property");
280-
return FAILURE;
281-
}
282-
/* }}} */
283-
284-
/* {{{ dom_register_prop_handler */
285268
static void dom_register_prop_handler(HashTable *prop_handler, char *name, size_t name_len, dom_read_t read_func, dom_write_t write_func)
286269
{
287270
dom_prop_handler hnd;
288271
zend_string *str;
289272

290-
hnd.read_func = read_func ? read_func : dom_read_na;
291-
hnd.write_func = write_func ? write_func : dom_write_na;
273+
hnd.read_func = read_func;
274+
hnd.write_func = write_func;
292275
str = zend_string_init_interned(name, name_len, 1);
293276
zend_hash_add_mem(prop_handler, str, &hnd, sizeof(dom_prop_handler));
294277
zend_string_release_ex(str, 1);
295278
}
296-
/* }}} */
297279

298-
static zval *dom_get_property_ptr_ptr(zend_object *object, zend_string *name, int type, void **cache_slot) /* {{{ */
280+
static zval *dom_get_property_ptr_ptr(zend_object *object, zend_string *name, int type, void **cache_slot)
299281
{
300282
dom_object *obj = php_dom_obj_from_obj(object);
301-
zval *retval = NULL;
302283

303284
if (!obj->prop_handler || !zend_hash_exists(obj->prop_handler, name)) {
304-
retval = zend_std_get_property_ptr_ptr(object, name, type, cache_slot);
285+
return zend_std_get_property_ptr_ptr(object, name, type, cache_slot);
305286
}
306-
return retval;
287+
288+
return NULL;
307289
}
308-
/* }}} */
309290

310291
/* {{{ dom_read_property */
311292
zval *dom_read_property(zend_object *object, zend_string *name, int type, void **cache_slot, zval *rv)
@@ -337,7 +318,6 @@ zval *dom_read_property(zend_object *object, zend_string *name, int type, void *
337318
}
338319
/* }}} */
339320

340-
/* {{{ dom_write_property */
341321
zval *dom_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot)
342322
{
343323
dom_object *obj = php_dom_obj_from_obj(object);
@@ -346,15 +326,32 @@ zval *dom_write_property(zend_object *object, zend_string *name, zval *value, vo
346326
if (obj->prop_handler != NULL) {
347327
hnd = zend_hash_find_ptr(obj->prop_handler, name);
348328
}
329+
349330
if (hnd) {
350-
hnd->write_func(obj, value);
351-
} else {
352-
value = zend_std_write_property(object, name, value, cache_slot);
331+
if (!hnd->write_func) {
332+
zend_throw_error(NULL, "Cannot write read-only property %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(name));
333+
return &EG(error_zval);
334+
}
335+
336+
zend_property_info *prop = zend_get_property_info(object->ce, name, /* silent */ true);
337+
if (prop && ZEND_TYPE_IS_SET(prop->type)) {
338+
zval tmp;
339+
ZVAL_COPY(&tmp, value);
340+
if (!zend_verify_property_type(prop, &tmp, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)))) {
341+
zval_ptr_dtor(&tmp);
342+
return &EG(error_zval);
343+
}
344+
hnd->write_func(obj, &tmp);
345+
zval_ptr_dtor(&tmp);
346+
} else {
347+
hnd->write_func(obj, value);
348+
}
349+
350+
return value;
353351
}
354352

355-
return value;
353+
return zend_std_write_property(object, name, value, cache_slot);
356354
}
357-
/* }}} */
358355

359356
/* {{{ dom_property_exists */
360357
static int dom_property_exists(zend_object *object, zend_string *name, int check_empty, void **cache_slot)

ext/dom/php_dom.stub.php

Lines changed: 19 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ class DOMNode
6161
/** @readonly */
6262
public string $nodeName;
6363

64-
/** @var string|null */
65-
public $nodeValue;
64+
public ?string $nodeValue;
6665

6766
/** @readonly */
6867
public int $nodeType;
@@ -94,17 +93,15 @@ class DOMNode
9493
/** @readonly */
9594
public ?string $namespaceURI;
9695

97-
/** @var string */
98-
public $prefix = "";
96+
public string $prefix;
9997

10098
/** @readonly */
10199
public ?string $localName;
102100

103101
/** @readonly */
104102
public ?string $baseURI;
105103

106-
/** @var string */
107-
public $textContent = "";
104+
public string $textContent;
108105

109106
/** @return DOMNode|false */
110107
public function appendChild(DOMNode $node) {}
@@ -415,53 +412,40 @@ class DOMDocument extends DOMNode implements DOMParentNode
415412
*/
416413
public ?string $actualEncoding;
417414

418-
/** @var string|null */
419-
public $encoding;
415+
public ?string $encoding;
420416

421417
/** @readonly */
422418
public ?string $xmlEncoding;
423419

424-
/** @var bool */
425-
public $standalone = false;
420+
public bool $standalone;
426421

427-
/** @var bool */
428-
public $xmlStandalone = false;
422+
public bool $xmlStandalone;
429423

430-
/** @var string|null */
431-
public $version;
424+
public ?string $version;
432425

433-
/** @var string|null */
434-
public $xmlVersion;
426+
public ?string $xmlVersion;
435427

436-
/** @var bool */
437-
public $strictErrorChecking = false;
428+
public bool $strictErrorChecking;
438429

439-
/** @var string|null */
440-
public $documentURI;
430+
public ?string $documentURI;
441431

442432
/**
443433
* @readonly
444434
* @deprecated
445435
*/
446436
public mixed $config = null;
447437

448-
/** @var bool */
449-
public $formatOutput = false;
438+
public bool $formatOutput;
450439

451-
/** @var bool */
452-
public $validateOnParse = false;
440+
public bool $validateOnParse;
453441

454-
/** @var bool */
455-
public $resolveExternals = false;
442+
public bool $resolveExternals;
456443

457-
/** @var bool */
458-
public $preserveWhiteSpace = false;
444+
public bool $preserveWhiteSpace;
459445

460-
/** @var bool */
461-
public $recover = false;
446+
public bool $recover;
462447

463-
/** @var bool */
464-
public $substituteEntities = false;
448+
public bool $substituteEntities;
465449

466450
/** @readonly */
467451
public ?DOMElement $firstElementChild;
@@ -580,7 +564,7 @@ public function prepend(...$nodes): void {}
580564

581565
final class DOMException extends Exception
582566
{
583-
/** @var int */
567+
/** @var int Intentionally left untyped */
584568
public $code = 0;
585569
}
586570

@@ -664,8 +648,7 @@ class DOMProcessingInstruction extends DOMNode
664648
/** @readonly */
665649
public string $target;
666650

667-
/** @var string */
668-
public $data = "";
651+
public string $data;
669652

670653
public function __construct(string $name, string $value = "") {}
671654
}
@@ -676,8 +659,7 @@ class DOMXPath
676659
/** @readonly */
677660
public DOMDocument $document;
678661

679-
/** @var bool */
680-
public $registerNodeNamespaces = false;
662+
public bool $registerNodeNamespaces;
681663

682664
public function __construct(DOMDocument $document, bool $registerNodeNS = true) {}
683665

0 commit comments

Comments
 (0)