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 <kevin@kdecherf.com>
This commit is contained in:
Kevin Decherf
2026-06-22 15:51:06 +02:00
parent a8b08d8cb2
commit 266e36c187
2 changed files with 18 additions and 1 deletions
+5 -1
View File
@@ -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;
}
+13
View File
@@ -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 = '<div><!-- comment --><code>some code snippet</code> ' . $text . '</div>';
$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