Fix GH-18877: \Dom\HTMLDocument querySelectorAll selecting only the first when using ~ and :has

Backports lexbor/lexbor@971faf11a5

Closes GH-19180.
This commit is contained in:
Niels Dossche 2025-07-19 01:04:37 +02:00
parent e990b691c5
commit aecf2a6e62
No known key found for this signature in database
GPG key ID: B8A8AD166DF0E2E5
4 changed files with 939 additions and 611 deletions

4
NEWS
View file

@ -8,6 +8,10 @@ PHP NEWS
. The $exclude_disabled parameter of the get_defined_functions() function has
been deprecated, as it no longer has any effect since PHP 8.0. (Girgias)
- DOM:
. Fixed bug GH-18877 (\Dom\HTMLDocument querySelectorAll selecting only the
first when using ~ and :has). (nielsdos, lexborisov)
- FileInfo
. The finfo_close() function has been deprecated. (timwolla)
. The $context parameter of the finfo_buffer() function has been deprecated

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2024 Alexander Borisov
* Copyright (C) 2021-2025 Alexander Borisov
*
* Author: Alexander Borisov <borisov@lexbor.com>
* Adapted for PHP libxml2 by: Niels Dossche <nielsdos@php.net>
@ -100,11 +100,13 @@ struct lxb_selectors_nested {
void *ctx;
const xmlNode *root;
lxb_selectors_entry_t *last;
lxb_selectors_nested_t *parent;
lxb_selectors_entry_t *first;
lxb_selectors_entry_t *top;
size_t index;
bool found;
bool forward;
};
struct lxb_selectors {
@ -113,7 +115,6 @@ struct lxb_selectors {
lexbor_dobject_t *nested;
lxb_selectors_nested_t *current;
lxb_selectors_entry_t *first;
lxb_selectors_opt_t options;
lxb_status_t status;

View file

@ -0,0 +1,30 @@
--TEST--
GH-18877 (\Dom\HTMLDocument querySelectorAll selecting only the first when using ~ and :has)
--EXTENSIONS--
dom
--FILE--
<?php
$text = <<<TEXT
<html>
<head>
</head>
<body>
<div><div></div></div>
<span>1</span>
<span>2</span>
<span>3</span>
</body>
</html>
TEXT;
$dom = \Dom\HTMLDocument::createFromString($text, options: LIBXML_NOERROR);
foreach ($dom->querySelectorAll('div:has(div) ~ *') as $node) {
var_dump($node->textContent);
}
?>
--EXPECT--
string(1) "1"
string(1) "2"
string(1) "3"