Skip to content

DOMElement::setAttribute() reaches EMPTY_SWITCH_DEFAULT_CASE() with DTD #FIXED default attributes #22825

Description

@alexandre-daubois

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

PHP >= 8.4.0

Operating System

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions