Skip to content

Fix GH-21544: Dom\XMLDocument::C14N() drops namespace declarations on…#21561

Open
devnexen wants to merge 2 commits intophp:PHP-8.4from
devnexen:gh21544
Open

Fix GH-21544: Dom\XMLDocument::C14N() drops namespace declarations on…#21561
devnexen wants to merge 2 commits intophp:PHP-8.4from
devnexen:gh21544

Conversation

@devnexen
Copy link
Copy Markdown
Member

… DOM-built documents.

For programmatically built documents (e.g. createElementNS), namespaces live on node->ns without corresponding xmlns attributes. Create temporary synthetic nsDef entries so C14N can find them, complementing the existing xmlns attribute to nsDef conversion.

… on DOM-built documents.

For programmatically built documents (e.g. createElementNS), namespaces
live on node->ns without corresponding xmlns attributes. Create temporary
synthetic nsDef entries so C14N can find them, complementing the existing
xmlns attribute to nsDef conversion.
@devnexen devnexen marked this pull request as ready for review March 28, 2026 10:04
@devnexen devnexen requested a review from ndossche as a code owner March 28, 2026 10:04
ext/dom/node.c Outdated
Comment on lines +2118 to +2135
xmlNsPtr ns = xmlMalloc(sizeof(*ns));
if (!ns) {
return;
}

zval *zv = zend_hash_index_lookup(links, (zend_ulong) node);
if (Z_ISNULL_P(zv)) {
ZVAL_LONG(zv, 1);
} else {
Z_LVAL_P(zv)++;
}

memset(ns, 0, sizeof(*ns));
ns->type = XML_LOCAL_NAMESPACE;
ns->href = xmlStrdup(src_ns->href);
ns->prefix = src_ns->prefix ? xmlStrdup(src_ns->prefix) : NULL;
ns->next = node->nsDef;
node->nsDef = ns;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it's a good idea to factor this out to a different function.

* entries during cleanup. */
static void dom_add_synthetic_ns_decl(HashTable *links, xmlNodePtr node, xmlNsPtr src_ns)
{
for (xmlNsPtr existing = node->nsDef; existing; existing = existing->next) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this loop? I believe that for Dom\XMLDocument this is normally never filled in.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The loop checks existing nsDef entries to avoid duplicates. While pre-existing nsDef is indeed empty for Dom\XMLDocument, the loop is still needed:
dom_add_synthetic_ns_decl is called multiple times per node (once for node->ns, once per attr->ns), and if the element and an attribute share the same namespace
prefix, the loop prevents adding a duplicate synthetic entry.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dom\XMLDocument::C14N() drops namespace declarations on DOM-built documents

2 participants