From 266e36c187724d096653f324706eff77446b8c09 Mon Sep 17 00:00:00 2001 From: Kevin Decherf Date: Sun, 21 Jun 2026 11:33:48 +0200 Subject: [PATCH] Fix a TypeError when tidy is disabled A logic tries to replace a node with its child node if it is the only element of the node. However in some cases, especially when tidy is disabled, children items other than DOMElement may survive (e.g. DOMComment), leading to a TypeError. Fixes #122 Signed-off-by: Kevin Decherf --- src/Readability.php | 6 +++++- tests/ReadabilityTest.php | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Readability.php b/src/Readability.php index e5f661a..f586909 100644 --- a/src/Readability.php +++ b/src/Readability.php @@ -1003,7 +1003,11 @@ class Readability implements LoggerAwareInterface } if ($this->hasSingleTagInsideElement($node, 'p') && $this->getLinkDensity($node) < 0.25) { - $newNode = $node->childNodes->item(0); + // In some cases when tidy is disabled the first item may not be a DOMElement so we apply a filter + $newNode = array_values(array_filter( + iterator_to_array($node->childNodes), + static fn ($childNode) => $childNode instanceof \DOMElement + ))[0]; $node->parentNode->replaceChild($newNode, $node); $nodesToScore[] = $newNode; } diff --git a/tests/ReadabilityTest.php b/tests/ReadabilityTest.php index e0844a1..cdaa69e 100644 --- a/tests/ReadabilityTest.php +++ b/tests/ReadabilityTest.php @@ -507,6 +507,19 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase $this->assertSame($expected, $method->invoke($readability, $node, $tag)); } + public function testDivToPElementWithComment(): void + { + $text = str_repeat('Padded real article text to reach decent length for content scoring threshold here. ', 8); + $html = '
some code snippet ' . $text . '
'; + + $readability = $this->getReadability($html, 'http://0.0.0.0', 'libxml', false); + $res = $readability->init(); + + $this->assertTrue($res); + $this->assertStringContainsString('some code snippet', $readability->getContent()->getInnerHtml()); + $this->assertStringContainsString('Padded real article text', $readability->getContent()->getInnerHtml()); + } + public function testKeepFootnotes(): void { // from https://www.schreibdichte.de/blog/feed-aggregator-und-spaeter-lesen-dienst-im-team