Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ PHP NEWS
that still have a live wrapper). (iliaal)
. Fixed a use-after-free when Dom\Element::setAttributeNS() replaces the
value of an attribute whose child still has a live wrapper. (iliaal)
. Fixed Dom\HTMLDocument::getElementById() not finding ids of SVG and
MathML elements. (Ilia Alshanetsky)
. Fixed Dom\HTMLDocument giving attributes the namespace of their element
when a fragment is parsed with an xlink, xml or xmlns context element.
(Ilia Alshanetsky)

- GD:
. Fixed imageaffinematrixget() and imageaffinematrixconcat() reporting the
Expand Down
8 changes: 4 additions & 4 deletions ext/dom/html5_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ static lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert(
lxml_attr->children = lxml_attr->last = lxml_text;
lxml_text->parent = (xmlNodePtr) lxml_attr;

if (attr->node.ns == LXB_NS_XMLNS) {
if (attr->node.ns == LXB_NS_XMLNS && (attr->node.prefix || strcmp((const char *) local_name, "xmlns") == 0)) {
if (strcmp((const char *) local_name, "xmlns") != 0) {
if (prefixed_xmlns_ns == NULL) {
prefixed_xmlns_ns = php_dom_libxml_ns_mapper_get_ns_raw_strings_nullsafe(ns_mapper, "xmlns", DOM_XMLNS_NS_URI);
Expand All @@ -251,13 +251,13 @@ static lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert(
lxml_attr->ns = php_dom_libxml_ns_mapper_ensure_prefixless_xmlns_ns(ns_mapper);
}
lxml_attr->ns->_private = (void *) php_dom_ns_is_xmlns_magic_token;
} else if (attr->node.ns == LXB_NS_XLINK) {
} else if (attr->node.prefix && attr->node.ns == LXB_NS_XLINK) {
if (xlink_ns == NULL) {
xlink_ns = php_dom_libxml_ns_mapper_get_ns_raw_strings_nullsafe(ns_mapper, "xlink", DOM_XLINK_NS_URI);
xlink_ns->_private = (void *) php_dom_ns_is_xlink_magic_token;
}
lxml_attr->ns = xlink_ns;
} else if (attr->node.ns == LXB_NS_XML) {
} else if (attr->node.prefix && attr->node.ns == LXB_NS_XML) {
if (xml_ns == NULL) {
xml_ns = php_dom_libxml_ns_mapper_get_ns_raw_strings_nullsafe(ns_mapper, "xml", DOM_XML_NS_URI);
xml_ns->_private = (void *) php_dom_ns_is_xml_magic_token;
Expand All @@ -274,7 +274,7 @@ static lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert(
last_added_attr = lxml_attr;

/* xmlIsID does some other stuff too that is irrelevant here. */
if (local_name_length == 2 && local_name[0] == 'i' && local_name[1] == 'd' && attr->node.ns == LXB_NS_HTML) {
if (local_name_length == 2 && local_name[0] == 'i' && local_name[1] == 'd' && lxml_attr->ns == NULL) {
if (xmlAddID(NULL, lxml_doc, value, lxml_attr) == 0) {
/* If the ID already exists, the ID attribute still needs to be marked as an ID. */
lxml_attr->atype = XML_ATTRIBUTE_ID;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
--TEST--
Unprefixed attributes in foreign content are in no namespace
--EXTENSIONS--
dom
--FILE--
<?php
$html = '<!DOCTYPE html><html><body><svg id="s" xlink:href="#a" xml:lang="en" xmlns:xlink="urn:x"><rect xml:id="r"/></svg><math id="m"></math><p id="p"></p></body></html>';
$doc = Dom\HTMLDocument::createFromString($html, LIBXML_NOERROR);

var_dump([
'svg #s' => $doc->getElementById('s')?->tagName,
'math #m' => $doc->getElementById('m')?->tagName,
'html #p' => $doc->getElementById('p')?->tagName,
'xml:id #r' => $doc->getElementById('r')?->tagName,
]);

foreach ($doc->getElementById('s')->attributes as $attr) {
echo $attr->name, ' => ', var_export($attr->namespaceURI, true), "\n";
}

$contexts = [
'http://www.w3.org/1999/xlink' => 'z',
'http://www.w3.org/XML/1998/namespace' => 'z',
'http://www.w3.org/2000/xmlns/' => 'xmlns',
];
foreach ($contexts as $uri => $name) {
$fragment_doc = Dom\HTMLDocument::createEmpty();
$context = $fragment_doc->createElementNS($uri, $name);
$fragment_doc->appendChild($context);
$context->innerHTML = '<z id="q" xlink:href="#a"></z>';

echo $uri, "\n ", $context->innerHTML, "\n ";
var_dump($fragment_doc->getElementById('q')?->tagName);
}
?>
--EXPECT--
array(4) {
["svg #s"]=>
string(3) "svg"
["math #m"]=>
string(4) "math"
["html #p"]=>
string(1) "P"
["xml:id #r"]=>
NULL
}
id => NULL
xlink:href => 'http://www.w3.org/1999/xlink'
xml:lang => 'http://www.w3.org/XML/1998/namespace'
xmlns:xlink => 'http://www.w3.org/2000/xmlns/'
http://www.w3.org/1999/xlink
<z id="q" xlink:href="#a"></z>
string(1) "Z"
http://www.w3.org/XML/1998/namespace
<z id="q" xlink:href="#a"></z>
string(1) "Z"
http://www.w3.org/2000/xmlns/
<z id="q" xlink:href="#a"></z>
string(1) "Z"
Loading