Skip to content

DOMChildNode replaceWith() double-free error when replacing elements not separated by any whitespace #9142

Closed
@bakerkretzmar

Description

@bakerkretzmar

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>).

https://3v4l.org/Y2vJc

PHP Version

8.0 and 8.1

Operating System

Whatever 3v4l.org is using, and macOS

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions