Skip to content

Commit c2bb921

Browse files
committed
dom: register unprefixed id attributes from foreign content in HTML
The HTML5 parser bridge only marked an id attribute as XML_ATTRIBUTE_ID when the attribute sat in the HTML namespace, so ids on SVG and MathML elements never reached getElementById(). The condition the bridge wants is that the attribute itself is unprefixed, which lxml_attr->ns already records: it is only set for the xmlns, xlink and xml namespaces.
1 parent 979c827 commit c2bb921

3 files changed

Lines changed: 29 additions & 1 deletion

File tree

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ PHP NEWS
2727
that still have a live wrapper). (iliaal)
2828
. Fixed a use-after-free when Dom\Element::setAttributeNS() replaces the
2929
value of an attribute whose child still has a live wrapper. (iliaal)
30+
. Fixed Dom\HTMLDocument::getElementById() not finding ids of SVG and
31+
MathML elements. (Ilia Alshanetsky)
3032

3133
- GD:
3234
. Fixed imageaffinematrixget() and imageaffinematrixconcat() reporting the

ext/dom/html5_parser.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ static lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert(
274274
last_added_attr = lxml_attr;
275275

276276
/* xmlIsID does some other stuff too that is irrelevant here. */
277-
if (local_name_length == 2 && local_name[0] == 'i' && local_name[1] == 'd' && attr->node.ns == LXB_NS_HTML) {
277+
if (local_name_length == 2 && local_name[0] == 'i' && local_name[1] == 'd' && lxml_attr->ns == NULL) {
278278
if (xmlAddID(NULL, lxml_doc, value, lxml_attr) == 0) {
279279
/* If the ID already exists, the ID attribute still needs to be marked as an ID. */
280280
lxml_attr->atype = XML_ATTRIBUTE_ID;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Dom\HTMLDocument::getElementById() finds ids of SVG and MathML elements
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
$html = '<!DOCTYPE html><html><body><svg id="s"><rect xml:id="r"/></svg><math id="m"></math><p id="p"></p></body></html>';
8+
$d = Dom\HTMLDocument::createFromString($html, LIBXML_NOERROR);
9+
var_dump([
10+
'svg #s' => $d->getElementById('s')?->tagName,
11+
'math #m' => $d->getElementById('m')?->tagName,
12+
'html #p' => $d->getElementById('p')?->tagName,
13+
'xml:id #r' => $d->getElementById('r')?->tagName,
14+
]);
15+
?>
16+
--EXPECT--
17+
array(4) {
18+
["svg #s"]=>
19+
string(3) "svg"
20+
["math #m"]=>
21+
string(4) "math"
22+
["html #p"]=>
23+
string(1) "P"
24+
["xml:id #r"]=>
25+
NULL
26+
}

0 commit comments

Comments
 (0)