[php-src] PR #25240: Fix combinators after a compound-leading selector-taking pseudo-class
| From: | phcorp | Date: | Fri, 06 Nov 2026 13:02:24 +0000 |
| Subject: | [php-src] PR #25240: Fix combinators after a compound-leading selector-taking pseudo-class | ||
| Groups: | php.git-pulls | ||
| Request: | Send a blank email to git-pulls+get-40353@lists.php.net to get a copy of this message | ||
Pull Request: https://github.com/php/php-src/pull/25240
Author: phcorp
When
:is(), :where(), :not(), :has() or
:nth-child(An+B of S) starts a compound selector, the combinator after it only checks
the nearest element. A descendant combinator acts like >, and ~ acts
like +:
```php
$d = Dom\HTMLDocument::createFromString('<!doctype
html><ul><li>a<ol><li>b</li></ol></li></ul>');
count($d->querySelectorAll(':is(ul) li')); // 1, expected 2
count($d->querySelectorAll('*:is(ul) li')); // 2
```
Reported upstream as lexbor/lexbor#436 and fixed there by lexbor/lexbor@f6c1d06. Dom\
uses its own adapted copy of the matcher, so updating the bundled lexbor doesn't pick up the
fix. This ports the same change into
ext/dom/lexbor/lexbor/selectors-adapted/selectors.c: when a nested selector rejects a
candidate, keep walking the descendant/subsequent-sibling combinator (and the child combinator in
forward mode) before backtracking to another entry.
lexbor436.phpt covers every selector from the upstream issue. It fails on PHP-8.4 HEAD
(8 of 8 cases) and passes with this change. The ext/dom suite passes. The patch applies cleanly to
PHP-8.5 and master.