Skip to content

Commit

Permalink
fix: DocumentFragment append does not cause error
Browse files Browse the repository at this point in the history
closes #453
  • Loading branch information
g105b committed Apr 25, 2024
1 parent b3fe4a5 commit b01b4be
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/ParentNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,18 @@ protected function __prop_get_children():HTMLCollection {
* returns the appended Node object.
* + Element.append() can append several nodes and strings, whereas
* Node.appendChild() can only append one node.
* @param Node|Element|Text|Comment|string...$nodes
* @param Node|Element|Text|Comment|DocumentFragment|string...$nodes
*/
public function append(...$nodes):void {
// Without this clumsy iteration, PHP 8.1 throws "free(): double free detected in tcache 2"
foreach($nodes as $node) {
/** @phpstan-ignore-next-line libxml's DOMNode does not define append() */
parent::append($node);
// And without this clumsy if/else, PHP 8.3 throws "double free or corruption (!prev)"
if(is_string($node)) {
parent::append($node);
}
else {
parent::appendChild($node);
}
}
}

Expand Down
14 changes: 14 additions & 0 deletions test/phpunit/DocumentFragmentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,18 @@ public function testGetElementById():void {
$sut->appendChild($nodeWithId);
self::assertSame($nodeWithId, $sut->getElementById("test"));
}

public function testAppendMultipleNodesThenAddToParentElement():void {
$document = new HTMLDocument();
$sut = $document->createDocumentFragment();
$expectedString = "";
for($i = 0; $i < 10; $i++) {
$textNode = $document->createTextNode("Node$i");
$sut->append($textNode);
$expectedString .= "Node$i";
}

$document->documentElement->append($sut);
self::assertSame($expectedString, $document->textContent);
}
}

0 comments on commit b01b4be

Please sign in to comment.