This is an automated email from the ASF dual-hosted git repository.
tballison pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tika.git
The following commit(s) were added to refs/heads/main by this push:
new a4384e9d49 TIKA-4963: JSoupParser keeps the text of CDATA sections
(#3311)
a4384e9d49 is described below
commit a4384e9d49a17fd3011c83820125d6bae00cee6e
Author: Tim Allison <[email protected]>
AuthorDate: Fri Oct 9 06:50:16 2026 -0400
TIKA-4963: JSoupParser keeps the text of CDATA sections (#3311)
---
CHANGES.txt | 4 ++++
.../org/apache/tika/parser/html/JSoupParser.java | 18 ++++++++++++++++++
.../org/apache/tika/parser/html/HtmlParserTest.java | 21 +++++++++++++++++++++
3 files changed, 43 insertions(+)
diff --git a/CHANGES.txt b/CHANGES.txt
index e2144fe4c0..c6fd60ed8c 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,9 @@
Release 4.2.0 - unreleased
+ * JSoupParser emits the text of CDATA sections again. jsoup 1.23 tokenizes
CDATA in
+ HTML content as a bogus comment, which silently dropped every CDATA value
in XML
+ that reaches the HTML parser (TIKA-4963).
+
* The text/html magic now requires the html tag to end, so an XML file with
an
element such as <htmlPath> in its first 8K is no longer detected as HTML
and sent
to the HTML parser (TIKA-4962).
diff --git
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/JSoupParser.java
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/JSoupParser.java
index 07c6470ca6..f5d33f6f50 100644
---
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/JSoupParser.java
+++
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/JSoupParser.java
@@ -32,6 +32,7 @@ import javax.xml.XMLConstants;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Attribute;
+import org.jsoup.nodes.Comment;
import org.jsoup.nodes.DataNode;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Node;
@@ -277,6 +278,23 @@ public class JSoupParser extends
AbstractEncodingDetectorParser {
}
}
return FilterResult.CONTINUE;
+ } else if (node instanceof Comment) {
+ // jsoup >= 1.23 tokenizes <![CDATA[...]]> in HTML content as
a bogus comment, as the
+ // HTML spec says. XML routed here as HTML keeps its CDATA
text through this branch;
+ // a bogus comment ends at the first '>', so a section
containing one is cut there.
+ String data = ((Comment) node).getData();
+ if (data != null && data.startsWith("[CDATA[")) {
+ int end = data.endsWith("]]") ? data.length() - 2 :
data.length();
+ char[] chars = data.substring(7, end).toCharArray();
+ try {
+ if (chars.length > 0) {
+ handler.characters(chars, 0, chars.length);
+ }
+ } catch (SAXException e) {
+ throw new RuntimeSAXException(e);
+ }
+ return FilterResult.SKIP_ENTIRELY;
+ }
}
AttributesImpl attributes = new AttributesImpl();
Iterator<Attribute> jsoupAttrs = node.attributes().iterator();
diff --git
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java
index ac998aad19..20dd94097f 100644
---
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java
+++
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java
@@ -341,6 +341,27 @@ public class HtmlParserTest extends TikaTest {
assertEquals("\u017d", metadata.get(TikaCoreProperties.TITLE));
}
+ /**
+ * XML that reaches the HTML parser keeps the text of its CDATA sections;
jsoup 1.23
+ * tokenizes CDATA in HTML content as a bogus comment.
+ */
+ @Test
+ public void testCdataInHtmlContent() throws Exception {
+ String test = "<flashTemplate><desc><![CDATA[Spread & bold
template]]></desc>"
+ + "<path><![CDATA[TmplData\\tmpl.html]]></path>"
+ + "<name>plain</name><!-- a real comment --></flashTemplate>";
+ BodyContentHandler body = new BodyContentHandler();
+ try (TikaInputStream tis = TikaInputStream.get(test.getBytes(UTF_8))) {
+ new JSoupParser().parse(tis, body, new Metadata(), new
ParseContext());
+ }
+ String content = body.toString();
+ assertTrue(content.contains("Spread & bold template"), content);
+ assertTrue(content.contains("TmplData\\tmpl.html"), content);
+ assertTrue(content.contains("plain"), content);
+ assertFalse(content.contains("a real comment"), content);
+ assertFalse(content.contains("CDATA"), content);
+ }
+
/**
* Test case for TIKA-341
*