Category
bug · AOT DOM live NodeList
Problem
Thin-AOT DOMElement::getElementsByTagName() boxes a NodeList with the right length but never sets JitDomGetElementsByTagNameUserScript::$lastTagQuery / $liveItemTagQuery (unlike DOMDocument::getElementsByTagName). DOMNodeList::item(0) then falls through to pinned-root firstChild, so $root->getElementsByTagName('b')->item(0) returns a. After a prior Document query that left lastTagQuery='*', Element * lists also include the element itself (Zend is descendants-only).
| Repro |
Zend 8.2+ |
AOT (master) |
$root->getElementsByTagName('b')->item(0)->nodeName alone |
b |
a |
$root->getElementsByTagName('*') names |
a,b,c |
root,a,b,c (after Document * poisoned tag) |
replaceChild($n, $root->getElementsByTagName('b')->item(0)) |
replaces b |
replaces a |
php-src reference
PHP implementation target
ext/dom/JitDomGetElementsByTagNameUserScript::tryInvokeFromElement — set $lastTagQuery / $liveItemTagQuery + from-element flag (peer Document tryInvoke)
ext/dom/JitDomLiveElementsByTagWalk / JitDomNodeListItemUserScript — when from-element, start walk at firstChild (exclude self)
Repro
./script/docker-exec.sh -- bash -lc 'php bin/compile.php -o /tmp/gebtn test/repro/issue_dom_element_getelements_item_aot.php && /tmp/gebtn'
Done when
Category
bug· AOT DOM live NodeListProblem
Thin-AOT
DOMElement::getElementsByTagName()boxes a NodeList with the rightlengthbut never setsJitDomGetElementsByTagNameUserScript::$lastTagQuery/$liveItemTagQuery(unlikeDOMDocument::getElementsByTagName).DOMNodeList::item(0)then falls through to pinned-rootfirstChild, so$root->getElementsByTagName('b')->item(0)returnsa. After a prior Document query that leftlastTagQuery='*', Element*lists also include the element itself (Zend is descendants-only).$root->getElementsByTagName('b')->item(0)->nodeNamealoneba$root->getElementsByTagName('*')namesa,b,croot,a,b,c(after Document*poisoned tag)replaceChild($n, $root->getElementsByTagName('b')->item(0))baphp-src reference
ext/dom/element.c—PHP_METHOD(DOMElement, getElementsByTagName)(descendants only)ext/dom/nodelist.c— liveitem()PHP implementation target
ext/dom/JitDomGetElementsByTagNameUserScript::tryInvokeFromElement— set$lastTagQuery/$liveItemTagQuery+ from-element flag (peer DocumenttryInvoke)ext/dom/JitDomLiveElementsByTagWalk/JitDomNodeListItemUserScript— when from-element, start walk atfirstChild(exclude self)Repro
./script/docker-exec.sh -- bash -lc 'php bin/compile.php -o /tmp/gebtn test/repro/issue_dom_element_getelements_item_aot.php && /tmp/gebtn'Done when
getElementsByTagName('b')->item(0)isbwithout a prior Document querygetElementsByTagName('*')is descendants-only (a,b,c)./script/aot-smoke.shstays 8/8