Skip to content

Commit cb1f932

Browse files
committed
Fix phpGH-20281: \Dom\Document::getElementById() is inconsistent after nodes are removed
This worked for non-parsed elements already, but not for elements where xmlAddID() returns early due to the ID already existing. In that case what was missing is marking the attribute as an ID. Closes phpGH-20283.
1 parent e9c9b1f commit cb1f932

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ PHP NEWS
1515
- DOM:
1616
. Partially fixed bug GH-16317 (DOM classes do not allow
1717
__debugInfo() overrides to work). (nielsdos)
18+
. Fixed bug GH-20281 (\Dom\Document::getElementById() is inconsistent
19+
after nodes are removed). (nielsdos)
1820

1921
- Exif:
2022
. Fix possible memory leak when tag is empty. (nielsdos)

ext/dom/html5_parser.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,10 @@ static lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert(
268268

269269
/* xmlIsID does some other stuff too that is irrelevant here. */
270270
if (local_name_length == 2 && local_name[0] == 'i' && local_name[1] == 'd' && attr->node.ns == LXB_NS_HTML) {
271-
xmlAddID(NULL, lxml_doc, value, lxml_attr);
271+
if (xmlAddID(NULL, lxml_doc, value, lxml_attr) == 0) {
272+
/* If the ID already exists, the ID attribute still needs to be marked as an ID. */
273+
lxml_attr->atype = XML_ATTRIBUTE_ID;
274+
}
272275
}
273276

274277
/* libxml2 doesn't support line numbers on this anyway, it derives them instead, so don't bother */
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
GH-20281 (\Dom\Document::getElementById() is inconsistent after nodes are removed)
3+
--EXTENSIONS--
4+
dom
5+
--CREDITS--
6+
cscott
7+
--FILE--
8+
<?php
9+
$d = \Dom\HTMLDocument::createFromString('<p id="a">b</p><p id="a">c</p>', LIBXML_NOERROR);
10+
$p = $d->getElementById('a');
11+
$p->remove();
12+
echo $d->getElementById('a')->textContent, "\n";
13+
?>
14+
--EXPECT--
15+
c

0 commit comments

Comments
 (0)