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 6620738735 [TIKA-4935] Delegate JAXP parser configuration to Apache 
Commons Secure (#3262)
6620738735 is described below

commit 6620738735af7c7fdf36495551d489c13344a51e
Author: Gary Gregory <[email protected]>
AuthorDate: Mon Sep 28 10:46:53 2026 -0400

    [TIKA-4935] Delegate JAXP parser configuration to Apache Commons Secure 
(#3262)
---
 .../java/org/apache/tika/utils/XMLReaderUtils.java |  6 +-
 .../org/apache/tika/utils/XMLReaderUtilsTest.java  | 73 ++++++++++++++++++++++
 2 files changed, 74 insertions(+), 5 deletions(-)

diff --git a/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java 
b/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java
index f519481358..62a27eda5f 100644
--- a/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java
+++ b/tika-core/src/main/java/org/apache/tika/utils/XMLReaderUtils.java
@@ -290,12 +290,8 @@ public class XMLReaderUtils implements Serializable {
             LOG.debug("XMLInputFactory class {}", factory.getClass());
         }
 
-        tryToSetStaxProperty(factory, XMLInputFactory.IS_NAMESPACE_AWARE, 
true);
-
-        //try to configure secure processing
-        tryToSetStaxProperty(factory, XMLInputFactory.IS_VALIDATING, false);
+        //try to cause DTDs to throw exceptions
         tryToSetStaxProperty(factory, XMLInputFactory.SUPPORT_DTD, false);
-        tryToSetStaxProperty(factory, 
XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
 
         trySetStaxSecurityManager(factory);
         return factory;
diff --git 
a/tika-core/src/test/java/org/apache/tika/utils/XMLReaderUtilsTest.java 
b/tika-core/src/test/java/org/apache/tika/utils/XMLReaderUtilsTest.java
index 42eb3a84d0..3a70f0aefc 100644
--- a/tika-core/src/test/java/org/apache/tika/utils/XMLReaderUtilsTest.java
+++ b/tika-core/src/test/java/org/apache/tika/utils/XMLReaderUtilsTest.java
@@ -17,6 +17,8 @@
 package org.apache.tika.utils;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.ByteArrayInputStream;
@@ -31,6 +33,8 @@ import java.util.NoSuchElementException;
 import javax.xml.stream.XMLEventReader;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.events.XMLEvent;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMResult;
@@ -138,6 +142,75 @@ public class XMLReaderUtilsTest {
         }
     }
 
+    @ParameterizedTest
+    @ValueSource(booleans = {false, true})
+    public void testStaxRejectsSmallInternalEntity(boolean eventReader) throws 
Exception {
+        // A single expansion stays below the limit, so this specifically 
guards disabled DTD processing.
+        String xml = "<!DOCTYPE root [<!ENTITY value 
'INTERNAL_CONTENT'>]><root>&value;</root>";
+        XMLInputFactory factory = XMLReaderUtils.getXMLInputFactory(new 
ParseContext());
+        if (eventReader) {
+            XMLEventReader reader = factory.createXMLEventReader(new 
StringReader(xml));
+            try {
+                assertThrows(XMLStreamException.class, () -> {
+                    while (reader.hasNext()) {
+                        reader.nextEvent();
+                    }
+                });
+            } finally {
+                reader.close();
+            }
+        } else {
+            XMLStreamReader reader = factory.createXMLStreamReader(new 
StringReader(xml));
+            try {
+                assertThrows(XMLStreamException.class, () -> {
+                    while (reader.hasNext()) {
+                        reader.next();
+                    }
+                });
+            } finally {
+                reader.close();
+            }
+        }
+    }
+
+    @Test
+    public void testStaxNamespaceAware() throws Exception {
+        // Coverage only: provider defaults preserve this behavior even 
without Tika's explicit settings.
+        XMLStreamReader reader = 
XMLReaderUtils.getXMLInputFactory().createXMLStreamReader(
+                new StringReader("<p:root xmlns:p='urn:tika:test' 
p:flag='value'/>"));
+        try {
+            assertEquals(XMLStreamReader.START_ELEMENT, reader.nextTag());
+            assertEquals("root", reader.getLocalName());
+            assertEquals("urn:tika:test", reader.getNamespaceURI());
+            assertEquals("value", reader.getAttributeValue("urn:tika:test", 
"flag"));
+        } finally {
+            reader.close();
+        }
+    }
+
+    @Test
+    public void testStaxDoesNotExposeReadableExternalEntity(@TempDir Path 
tempDir) throws Exception {
+        // Coverage only: Commons Secure XML also blocks this content when DTD 
support is enabled.
+        Path external = tempDir.resolve("entity.txt");
+        Files.writeString(external, "EXTERNAL_CONTENT", 
StandardCharsets.UTF_8);
+        String xml = "<!DOCTYPE root [<!ENTITY value SYSTEM '" + 
external.toUri() + "'>]><root>&value;</root>";
+        XMLEventReader reader = 
XMLReaderUtils.getXMLInputFactory().createXMLEventReader(new StringReader(xml));
+        StringBuilder text = new StringBuilder();
+        try {
+            while (reader.hasNext()) {
+                XMLEvent event = reader.nextEvent();
+                if (event.isCharacters()) {
+                    text.append(event.asCharacters().getData());
+                }
+            }
+        } catch (XMLStreamException e) {
+            // Rejecting the entity is also acceptable; inspect any content 
delivered before rejection.
+        } finally {
+            reader.close();
+        }
+        assertFalse(text.toString().contains("EXTERNAL_CONTENT"), 
text.toString());
+    }
+
     @Test
     public void testStax() throws Exception {
         for (String xml : EXTERNAL_ENTITY_XMLS) {

Reply via email to