Description
Originally reported by @ExPatch-LLC
Calling DOMElement::setAttribute() with an attribute name that resolves to a DTD #FIXED default attribute reaches an EMPTY_SWITCH_DEFAULT_CASE() in ext/dom/element.c.
The following code:
<?php
$doc = new DOMDocument();
$doc->loadXML('<!DOCTYPE root [<!ATTLIST root A CDATA #FIXED "d">]><root/>');
$doc->documentElement->setAttribute('A', 'v');
Resulted in this output (debug build):
php: ext/dom/element.c:469: zim_DOMElement_setAttribute: Assertion `0' failed.
Aborted (core dumped)
But I expected this output instead: no crash, a new attribute is created on the element (as happens on 8.1-8.3).
On the legacy (non-spec-compliant) path, dom_get_attribute_or_nsdecl() -> xmlHasNsProp() falls back to the DTD and returns an xmlAttribute node (XML_ATTRIBUTE_DECL, type 16). The switch (attr->type) in setAttribute() only handles XML_ATTRIBUTE_NODE and XML_NAMESPACE_DECL, so a type-16 node hits the EMPTY_SWITCH_DEFAULT_CASE() branch.
This was introduced in 14b6c98. Before that, the default branch was a plain default: break;, which is why 8.1-8.3 are unaffected.
PHP Version
Operating System
No response
Description
Originally reported by @ExPatch-LLC
Calling
DOMElement::setAttribute()with an attribute name that resolves to a DTD #FIXED default attribute reaches anEMPTY_SWITCH_DEFAULT_CASE()inext/dom/element.c.The following code:
Resulted in this output (debug build):
But I expected this output instead: no crash, a new attribute is created on the element (as happens on 8.1-8.3).
On the legacy (non-spec-compliant) path,
dom_get_attribute_or_nsdecl()->xmlHasNsProp()falls back to the DTD and returns anxmlAttributenode (XML_ATTRIBUTE_DECL, type 16). Theswitch (attr->type)insetAttribute()only handlesXML_ATTRIBUTE_NODEandXML_NAMESPACE_DECL, so a type-16 node hits theEMPTY_SWITCH_DEFAULT_CASE()branch.This was introduced in 14b6c98. Before that, the default branch was a plain
default: break;, which is why 8.1-8.3 are unaffected.PHP Version
Operating System
No response