Skip to content

Namespace reuse in createElementNS() generates wrong output #11500

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ausi opened this issue Jun 21, 2023 · 0 comments
Closed

Namespace reuse in createElementNS() generates wrong output #11500

ausi opened this issue Jun 21, 2023 · 0 comments

Comments

@ausi
Copy link

ausi commented Jun 21, 2023

Description

The following code:

<?php
$dom = new \DOMDocument();
$root = $dom->createElementNS('http://example.com', 'root');
$dom->appendChild($root);

$a1 = $dom->createElementNS('http://example.com', 'a');
$a1->appendChild($dom->createElementNS('http://example.com', 'b'));
$root->appendChild($a1);

$a2 = $dom->createElementNS('http://example.com', 'a');
$a2->appendChild($dom->createElementNS('http://example.com', 'b'));
$root->appendChild($a2);

echo $dom->saveXML();

Resulted in this output:

<?xml version="1.0"?>
<root xmlns="http://example.com"><a><b/></a><a><b xmlns="http://example.com"/></a></root>

But I expected this output instead:

<?xml version="1.0"?>
<root xmlns="http://example.com"><a><b/></a><a><b/></a></root>

Only the nightly build from the master branch seems to be affected.
With the stable releases this bug does not occur, see https://3v4l.org/hAXOS

Related: #11428 (comment)

PHP Version

8.3.0-dev fe6263e
ext-dom: 20031129
lib-libxml: 2.9.4

Operating System

No response

nielsdos added a commit to nielsdos/php-src that referenced this issue Jun 25, 2023
… output

When you construct a DOM tree containing subtrees which are constructed
top-down, this won't remove the redundant namespaces. That's because the
following conditions hold:
1) The namespace are reused from the doc->oldNs list.
2) Therefore during reconciliation no nsDef field is set, so no redundant
   namespaces are removed by our reconciliation code.

Furthermore, it would only be fixed up automatically if the tree wasn't
added in bottom-up way, or if it had been constructed bottom-up from the
start.

Fix it by setting a flag to remove redundant namespaces in the libxml2
reconciliation call.
Since removing redundant namespaces may have a performance cost, we only do
this after performing a simple check.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants