From 0fbea5e4cfb4dc94c6ea0f3d8cb1a947162e88b2 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 27 Dec 2025 19:22:32 +0000
Subject: [PATCH 1/3] Initial plan
From 1e089bf8621848951eb45ceaa54d94a0571aa499 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 27 Dec 2025 19:33:18 +0000
Subject: [PATCH 2/3] Fix DOMDocument loadHTML warnings by suppressing libxml
errors
Co-authored-by: jschroed91 <2540804+jschroed91@users.noreply.github.com>
---
.phpunit.result.cache | 1 +
lib/Caxy/HtmlDiff/ListDiffLines.php | 14 ++++++
lib/Caxy/HtmlDiff/Table/TableDiff.php | 7 +++
.../HtmlDiff/nested-list-warning.html | 46 +++++++++++++++++++
4 files changed, 68 insertions(+)
create mode 100644 .phpunit.result.cache
create mode 100644 tests/fixtures/HtmlDiff/nested-list-warning.html
diff --git a/.phpunit.result.cache b/.phpunit.result.cache
new file mode 100644
index 0000000..dfec038
--- /dev/null
+++ b/.phpunit.result.cache
@@ -0,0 +1 @@
+{"version":1,"defects":[],"times":{"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"ICC-5136.html\"":0.012,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"first-and-last.html\"":0.009,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"issue-28-link-changes.html\"":0.005,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"keep-newlines-test.html\"":0.003,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"multibyte.html\"":0.001,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"multiline-tag.html\"":0,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"nested-list-warning.html\"":0.012,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"new-paragraph-and-list.html\"":0.071,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"override-2.html\"":0.008,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"override-3.html\"":0.026,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"override-4.html\"":0.025,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"override-5.html\"":0.059,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"override-6.html\"":0.031,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"override-8.html\"":0.016,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"override-9.html\"":0.005,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"simple-list.html\"":0.017,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"space-inside-isolated-tag.html\"":0.003,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"spaces-added.html\"":0.001,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"spaces-removed-inside-tag.html\"":0.003,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"table-whitespace-issue.html\"":0.011,"Caxy\\Tests\\HtmlDiff\\Functional\\HTMLPurifierConfigTest::testHtmlDiffConfigTraditional":0.026,"Caxy\\Tests\\HtmlDiff\\Functional\\HTMLPurifierConfigTest::testHtmlDiffConfigStatic":0.005}}
\ No newline at end of file
diff --git a/lib/Caxy/HtmlDiff/ListDiffLines.php b/lib/Caxy/HtmlDiff/ListDiffLines.php
index cfc68c7..ea3cb8c 100644
--- a/lib/Caxy/HtmlDiff/ListDiffLines.php
+++ b/lib/Caxy/HtmlDiff/ListDiffLines.php
@@ -87,12 +87,19 @@ protected function listByLines(string $old, string $new) : string
$new = mb_encode_numericentity($new, [0x80, 0x10FFFF, 0, ~0], 'UTF-8');
$old = mb_encode_numericentity($old, [0x80, 0x10FFFF, 0, ~0], 'UTF-8');
+ // Suppress libxml errors to avoid warnings from malformed HTML fragments
+ $previousLibxmlUseInternalErrors = libxml_use_internal_errors(true);
+
$newDom = new DOMDocument();
$newDom->loadHTML($new);
$oldDom = new DOMDocument();
$oldDom->loadHTML($old);
+ // Restore previous libxml error handling state
+ libxml_clear_errors();
+ libxml_use_internal_errors($previousLibxmlUseInternalErrors);
+
$newListNode = $this->findListNode($newDom);
$oldListNode = $this->findListNode($oldDom);
@@ -405,9 +412,16 @@ private function setInnerHtml(DOMNode $node, string $html) : void
$node->nodeValue = '';
+ // Suppress libxml errors to avoid warnings from malformed HTML fragments
+ $previousLibxmlUseInternalErrors = libxml_use_internal_errors(true);
+
$bufferDom = new DOMDocument('1.0', 'UTF-8');
$bufferDom->loadHTML($html);
+ // Restore previous libxml error handling state
+ libxml_clear_errors();
+ libxml_use_internal_errors($previousLibxmlUseInternalErrors);
+
$bodyNode = $bufferDom->getElementsByTagName('body')->item(0);
foreach ($bodyNode->childNodes as $childNode) {
diff --git a/lib/Caxy/HtmlDiff/Table/TableDiff.php b/lib/Caxy/HtmlDiff/Table/TableDiff.php
index ed46d94..4ff899f 100644
--- a/lib/Caxy/HtmlDiff/Table/TableDiff.php
+++ b/lib/Caxy/HtmlDiff/Table/TableDiff.php
@@ -626,9 +626,16 @@ protected function buildTableDoms()
*/
protected function createDocumentWithHtml($text)
{
+ // Suppress libxml errors to avoid warnings from malformed HTML fragments
+ $previousLibxmlUseInternalErrors = libxml_use_internal_errors(true);
+
$dom = new \DOMDocument();
$dom->loadHTML(htmlspecialchars_decode(iconv('UTF-8', 'ISO-8859-1//IGNORE', htmlentities($text, ENT_COMPAT, 'UTF-8')), ENT_QUOTES));
+ // Restore previous libxml error handling state
+ libxml_clear_errors();
+ libxml_use_internal_errors($previousLibxmlUseInternalErrors);
+
return $dom;
}
diff --git a/tests/fixtures/HtmlDiff/nested-list-warning.html b/tests/fixtures/HtmlDiff/nested-list-warning.html
new file mode 100644
index 0000000..1a4d590
--- /dev/null
+++ b/tests/fixtures/HtmlDiff/nested-list-warning.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
This sentence.
+
+
+
:
+
+
Another item
+
+
+
+
+
:
+
Saturn
+
+
+
+
+
+
This sentence.
+
+
+
:
+
+
Another item
+
+
+
:
+
+
Saturn
+
+
+
+
+
+
+
This sentence.
+
+
:
+
This sentence.
Another item
:
+
Another item
Saturn
:
Saturn
From 2c1e3d70f7038d2ff3e70ed5c2efb9179c9c0bfc Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 27 Dec 2025 19:34:13 +0000
Subject: [PATCH 3/3] Add .phpunit.result.cache to .gitignore
Co-authored-by: jschroed91 <2540804+jschroed91@users.noreply.github.com>
---
.gitignore | 3 ++-
.phpunit.result.cache | 1 -
2 files changed, 2 insertions(+), 2 deletions(-)
delete mode 100644 .phpunit.result.cache
diff --git a/.gitignore b/.gitignore
index 183037e..318cfe6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@ vendor/
/demo/bower_components
/demo/node_modules
.DS_Store
-.idea
\ No newline at end of file
+.idea
+.phpunit.result.cache
\ No newline at end of file
diff --git a/.phpunit.result.cache b/.phpunit.result.cache
deleted file mode 100644
index dfec038..0000000
--- a/.phpunit.result.cache
+++ /dev/null
@@ -1 +0,0 @@
-{"version":1,"defects":[],"times":{"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"ICC-5136.html\"":0.012,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"first-and-last.html\"":0.009,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"issue-28-link-changes.html\"":0.005,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"keep-newlines-test.html\"":0.003,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"multibyte.html\"":0.001,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"multiline-tag.html\"":0,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"nested-list-warning.html\"":0.012,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"new-paragraph-and-list.html\"":0.071,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"override-2.html\"":0.008,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"override-3.html\"":0.026,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"override-4.html\"":0.025,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"override-5.html\"":0.059,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"override-6.html\"":0.031,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"override-8.html\"":0.016,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"override-9.html\"":0.005,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"simple-list.html\"":0.017,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"space-inside-isolated-tag.html\"":0.003,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"spaces-added.html\"":0.001,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"spaces-removed-inside-tag.html\"":0.003,"Caxy\\Tests\\HtmlDiff\\Functional\\HtmlDiffFunctionalTest::testHtmlDiff with data set \"table-whitespace-issue.html\"":0.011,"Caxy\\Tests\\HtmlDiff\\Functional\\HTMLPurifierConfigTest::testHtmlDiffConfigTraditional":0.026,"Caxy\\Tests\\HtmlDiff\\Functional\\HTMLPurifierConfigTest::testHtmlDiffConfigStatic":0.005}}
\ No newline at end of file