Closed
Description
Description
Two XML/HTML elements that are immediately following each other, without any space in between them, cause a 'double free' error if you try to call replaceWith()
on them.
$document = '<var>One</var><var>Two</var>';
($dom = new DOMDocument('1.0', 'UTF-8'))->loadHTML($document);
foreach ((new DOMXPath($dom))->query('//var') as $var) {
$var->replaceWith($dom->createElement('p', $var->nodeValue));
}
var_dump($dom->saveHTML());
From 3v4l.org (note that the first element is successfully replaced):
string(158) "<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>One</p><var>Two</var></body></html>
"
free(): double free detected in tcache 2
Process exited with code 134.
Locally (macOS, inside a PHPUnit test, also exits with code 134):
php(1575,0x1016a8580) malloc: *** error for object 0x600002a642f0: pointer being freed was not allocated
php(1575,0x1016a8580) malloc: *** set a breakpoint in malloc_error_break to debug
Expected (both <var>
s replaced and no error):
string(158) "<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>One</p><p>Two</p></body></html>
"
Note:
- There's no error if the two
<var>
elements are separated by a line break or space. - This happens with any elements, not just custom ones (e.g.
<span>
,<p>
).
PHP Version
8.0 and 8.1
Operating System
Whatever 3v4l.org is using, and macOS