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 64deef8cb6 improve depth limits (#3319)
64deef8cb6 is described below
commit 64deef8cb69fc8a0c56dd28a4bdef71b794203a3
Author: Tim Allison <[email protected]>
AuthorDate: Mon Oct 12 12:47:16 2026 -0400
improve depth limits (#3319)
---
.../ROOT/pages/advanced/setting-limits.adoc | 11 +++---
.../pages/migration-to-4x/migrating-to-4x.adoc | 10 +++++
.../org/apache/tika/config/EmbeddedLimits.java | 6 ++-
.../java/org/apache/tika/config/OutputLimits.java | 46 +++++++++++++++-------
.../apache/tika/parser/RecursiveParserWrapper.java | 37 ++++++++++++++++-
.../org/apache/tika/sax/SecureContentHandler.java | 28 +++++++++++--
.../apache/tika/sax/SecureContentHandlerTest.java | 2 +-
.../tika/parser/RecursiveParserWrapperTest.java | 23 +++++++++++
.../tika/parser/pkg/CompressorParserTest.java | 6 +--
.../org/apache/tika/parser/pkg/ZipParserTest.java | 9 ++---
.../java/org/apache/tika/config/AllLimitsTest.java | 2 +-
.../org/apache/tika/config/EmbeddedLimitsTest.java | 6 +--
.../org/apache/tika/config/OutputLimitsTest.java | 2 +-
.../apache/tika/config/loader/TikaLoaderTest.java | 4 +-
14 files changed, 146 insertions(+), 46 deletions(-)
diff --git a/docs/modules/ROOT/pages/advanced/setting-limits.adoc
b/docs/modules/ROOT/pages/advanced/setting-limits.adoc
index 2f8c208cf6..957fe2e9e1 100644
--- a/docs/modules/ROOT/pages/advanced/setting-limits.adoc
+++ b/docs/modules/ROOT/pages/advanced/setting-limits.adoc
@@ -30,7 +30,7 @@ throughout the parse.
|`embedded-limits`
|`EmbeddedLimits`
-|Depth and count of embedded documents. Unlimited by default.
+|Depth and count of embedded documents. Depth 20, count unlimited by default.
|`output-limits`
|`OutputLimits`
@@ -74,7 +74,6 @@ these but `exception-reporting`, which has its own test:
"writeLimit": 100000,
"throwOnWriteLimit": false,
"maxXmlDepth": 100,
- "maxPackageEntryDepth": 10,
"zipBombThreshold": 1000000,
"zipBombRatio": 100
},
@@ -131,7 +130,7 @@ Tests: `AllLimitsTest`, `EmbeddedLimitsTest`,
`OutputLimitsTest`, `TimeoutLimits
|Setting |Default |Description
|`maxDepth`
-|-1 (unlimited)
+|20
|Maximum nesting depth. Recursion stops at the limit; siblings at the current
level still parse.
@@ -184,8 +183,10 @@ container.zip (depth 0)
|Maximum XML element nesting depth. Guards against XML bombs.
|`maxPackageEntryDepth`
-|10
-|Maximum depth of nested package entries (zip within zip).
+|20
+|Deprecated in 4.2, removed in 4.3; use `embedded-limits` `maxDepth`, which
+bounds nesting on every path. Counts nested package entries only when embedded
+content is inlined into its container's XHTML.
|`zipBombThreshold`
|1,000,000
diff --git a/docs/modules/ROOT/pages/migration-to-4x/migrating-to-4x.adoc
b/docs/modules/ROOT/pages/migration-to-4x/migrating-to-4x.adoc
index 28b7fd7d44..3b57b0e67e 100644
--- a/docs/modules/ROOT/pages/migration-to-4x/migrating-to-4x.adoc
+++ b/docs/modules/ROOT/pages/migration-to-4x/migrating-to-4x.adoc
@@ -268,6 +268,16 @@ Configure the engine under `engines` and name it in
`text-recognizers` (or bind
excluding `pdf-parser` goes with it: the 4.2 shape is `"pages": {"text":
"OCR"}` with the
VLM as recognizer, which sends rendered pages rather than the file.
+=== Embedded depth defaults and `maxPackageEntryDepth` deprecated (4.2.0+)
+
+`embedded-limits` `maxDepth` defaults to 20 (was unlimited) on every path.
`output-limits`
+`maxPackageEntryDepth` is deprecated and removed in 4.3.0, after which a
config that sets it
+fails to load; it logs a WARN when set. Until then it defaults to 20 (was 10,
which allowed
+only 9 levels). A concatenated parse of a deeply nested archive now stops at
depth 20 and sets
+`tk:exception:embedded-depth-limit-reached` instead of throwing. The zip-bomb
ratio now
+applies across the whole document tree on the `/rmeta` path, as it already did
on the
+concatenated path, and fails the parse with `Zip bomb detected!`.
+
=== Embedding filters and the image embedding parser deprecated (4.1.0+)
`openai-embedding-filter`, `jina-embedding-filter` and
`openai-image-embedding-parser` are
diff --git a/tika-core/src/main/java/org/apache/tika/config/EmbeddedLimits.java
b/tika-core/src/main/java/org/apache/tika/config/EmbeddedLimits.java
index 4bf8f86341..653e553421 100644
--- a/tika-core/src/main/java/org/apache/tika/config/EmbeddedLimits.java
+++ b/tika-core/src/main/java/org/apache/tika/config/EmbeddedLimits.java
@@ -25,7 +25,7 @@ import org.apache.tika.parser.ParseContext;
* <p>
* This controls how deep and how many embedded documents are processed:
* <ul>
- * <li>{@code maxDepth} - maximum nesting depth for embedded documents (-1 =
unlimited)</li>
+ * <li>{@code maxDepth} - maximum nesting depth for embedded documents
(default: 20, -1 = unlimited)</li>
* <li>{@code throwOnMaxDepth} - whether to throw an exception when maxDepth
is reached</li>
* <li>{@code maxCount} - maximum number of embedded documents to process
(-1 = unlimited)</li>
* <li>{@code throwOnMaxCount} - whether to throw an exception when maxCount
is reached</li>
@@ -74,7 +74,9 @@ public class EmbeddedLimits implements Serializable {
public static final int UNLIMITED = -1;
- private int maxDepth = UNLIMITED;
+ public static final int DEFAULT_MAX_DEPTH = 20;
+
+ private int maxDepth = DEFAULT_MAX_DEPTH;
private boolean throwOnMaxDepth = false;
private int maxCount = UNLIMITED;
private boolean throwOnMaxCount = false;
diff --git a/tika-core/src/main/java/org/apache/tika/config/OutputLimits.java
b/tika-core/src/main/java/org/apache/tika/config/OutputLimits.java
index 46ebad5c76..0e7bd540b9 100644
--- a/tika-core/src/main/java/org/apache/tika/config/OutputLimits.java
+++ b/tika-core/src/main/java/org/apache/tika/config/OutputLimits.java
@@ -17,6 +17,9 @@
package org.apache.tika.config;
import java.io.Serializable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import org.apache.tika.annotation.TikaComponent;
import org.apache.tika.parser.ParseContext;
@@ -28,7 +31,7 @@ import org.apache.tika.parser.ParseContext;
* <li>{@code writeLimit} - maximum characters to write (-1 = unlimited)</li>
* <li>{@code throwOnWriteLimit} - whether to throw an exception when
writeLimit is reached</li>
* <li>{@code maxXmlDepth} - maximum XML element nesting depth (default:
100)</li>
- * <li>{@code maxPackageEntryDepth} - maximum package entry nesting depth
(default: 10)</li>
+ * <li>{@code maxPackageEntryDepth} - deprecated; use {@link
EmbeddedLimits#setMaxDepth(int)}</li>
* <li>{@code zipBombThreshold} - characters before zip bomb check activates
(default: 1,000,000)</li>
* <li>{@code zipBombRatio} - maximum output:input ratio for zip bomb
detection (default: 100)</li>
* </ul>
@@ -40,7 +43,7 @@ import org.apache.tika.parser.ParseContext;
* <li>If {@code throwOnWriteLimit=true}: {@code WriteLimitReachedException}
is thrown</li>
* </ul>
* <p>
- * <b>Security limits:</b> maxXmlDepth, maxPackageEntryDepth, and zipBomb
+ * <b>Security limits:</b> maxXmlDepth and zipBomb
* limits always throw exceptions when exceeded (no silent truncation option).
* <p>
* Example configuration:
@@ -51,8 +54,7 @@ import org.apache.tika.parser.ParseContext;
* "writeLimit": 100000,
* "throwOnWriteLimit": false,
* "maxXmlDepth": 100,
- * "maxPackageEntryDepth": 10,
- * "zipBombThreshold": 1000000,
+ * * "zipBombThreshold": 1000000,
* "zipBombRatio": 100
* }
* }
@@ -66,6 +68,8 @@ public class OutputLimits implements Serializable {
private static final long serialVersionUID = 1L;
+ private static final Logger LOG =
LoggerFactory.getLogger(OutputLimits.class);
+
public static final int UNLIMITED = -1;
// Output limits
@@ -74,7 +78,7 @@ public class OutputLimits implements Serializable {
// XML/Security limits
private int maxXmlDepth = 100;
- private int maxPackageEntryDepth = 10;
+ private int maxPackageEntryDepth = 20;
private long zipBombThreshold = 1_000_000;
private long zipBombRatio = 100;
@@ -90,21 +94,31 @@ public class OutputLimits implements Serializable {
* @param writeLimit maximum characters to write (-1 = unlimited)
* @param throwOnWriteLimit whether to throw when write limit is reached
* @param maxXmlDepth maximum XML element nesting depth
- * @param maxPackageEntryDepth maximum package entry nesting depth
* @param zipBombThreshold characters before zip bomb check activates
* @param zipBombRatio maximum output:input ratio
*/
- public OutputLimits(int writeLimit, boolean throwOnWriteLimit,
- int maxXmlDepth, int maxPackageEntryDepth,
+ public OutputLimits(int writeLimit, boolean throwOnWriteLimit, int
maxXmlDepth,
long zipBombThreshold, long zipBombRatio) {
this.writeLimit = writeLimit;
this.throwOnWriteLimit = throwOnWriteLimit;
this.maxXmlDepth = maxXmlDepth;
- this.maxPackageEntryDepth = maxPackageEntryDepth;
this.zipBombThreshold = zipBombThreshold;
this.zipBombRatio = zipBombRatio;
}
+ /**
+ * @deprecated package-entry depth only bounds nesting when embedded
content is
+ * inlined into its container's XHTML; use {@link
EmbeddedLimits#setMaxDepth(int)},
+ * which bounds nesting on every path. To be removed in 4.3.
+ */
+ @Deprecated(since = "4.2", forRemoval = true)
+ public OutputLimits(int writeLimit, boolean throwOnWriteLimit,
+ int maxXmlDepth, int maxPackageEntryDepth,
+ long zipBombThreshold, long zipBombRatio) {
+ this(writeLimit, throwOnWriteLimit, maxXmlDepth, zipBombThreshold,
zipBombRatio);
+ setMaxPackageEntryDepth(maxPackageEntryDepth);
+ }
+
/**
* Gets the maximum characters to write.
*
@@ -160,20 +174,22 @@ public class OutputLimits implements Serializable {
}
/**
- * Gets the maximum package entry nesting depth.
- *
- * @return maximum package entry depth
+ * @deprecated use {@link EmbeddedLimits#getMaxDepth()}. To be removed in
4.3.
*/
+ @Deprecated(since = "4.2", forRemoval = true)
public int getMaxPackageEntryDepth() {
return maxPackageEntryDepth;
}
/**
- * Sets the maximum package entry nesting depth.
- *
- * @param maxPackageEntryDepth maximum package entry depth
+ * @deprecated package-entry depth only bounds nesting when embedded
content is
+ * inlined into its container's XHTML; use {@link
EmbeddedLimits#setMaxDepth(int)},
+ * which bounds nesting on every path. To be removed in 4.3.
*/
+ @Deprecated(since = "4.2", forRemoval = true)
public void setMaxPackageEntryDepth(int maxPackageEntryDepth) {
+ LOG.warn("maxPackageEntryDepth is deprecated and will be removed in
4.3; " +
+ "use embedded-limits maxDepth");
this.maxPackageEntryDepth = maxPackageEntryDepth;
}
diff --git
a/tika-core/src/main/java/org/apache/tika/parser/RecursiveParserWrapper.java
b/tika-core/src/main/java/org/apache/tika/parser/RecursiveParserWrapper.java
index c905bfba22..24fadc464d 100644
--- a/tika-core/src/main/java/org/apache/tika/parser/RecursiveParserWrapper.java
+++ b/tika-core/src/main/java/org/apache/tika/parser/RecursiveParserWrapper.java
@@ -24,6 +24,7 @@ import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
+import org.apache.tika.config.OutputLimits;
import org.apache.tika.exception.CorruptedFileException;
import org.apache.tika.exception.EncryptedDocumentException;
import org.apache.tika.exception.TikaException;
@@ -162,9 +163,10 @@ public class RecursiveParserWrapper extends
ParserDecorator {
throwOnWriteLimitReached =
((WriteLimiter)factory).isThrowOnWriteLimitReached();
}
}
+ SecureHandlerCounter handlerCounter = new
SecureHandlerCounter(writeLimit, tis);
try {
RecursivelySecureContentHandler secureContentHandler =
- new RecursivelySecureContentHandler(localHandler, tis, new
SecureHandlerCounter(writeLimit),
+ new RecursivelySecureContentHandler(localHandler, tis,
handlerCounter,
throwOnWriteLimitReached, context);
context.set(RecursivelySecureContentHandler.class,
secureContentHandler);
getWrappedParser().parse(tis, secureContentHandler, metadata,
context);
@@ -177,6 +179,9 @@ public class RecursiveParserWrapper extends ParserDecorator
{
} else {
metadata.add(TikaCoreProperties.CONTAINER_EXCEPTION,
ExceptionUtils.format(e, context));
+ if (handlerCounter.zipBombDetected) {
+ throw new TikaException("Zip bomb detected!", e);
+ }
throw e;
}
} finally {
@@ -281,6 +286,8 @@ public class RecursiveParserWrapper extends ParserDecorator
{
if (WriteLimitReachedException.isWriteLimitReached(e)) {
metadata.add(TikaCoreProperties.WRITE_LIMIT_REACHED,
"true");
throw e;
+ } else if (preParseHandler.handlerCounter.zipBombDetected) {
+ throw e;
} else {
if (catchEmbeddedExceptions) {
ParserUtils.recordParserFailure(this, e, metadata,
context);
@@ -334,9 +341,15 @@ public class RecursiveParserWrapper extends
ParserDecorator {
private boolean writeLimitReached = false;
//total chars written to all handlers
private int totalChars = 0;
+ //the container's stream: the denominator for the compression ratio
across the tree
+ private final TikaInputStream rootStream;
+ //total chars produced by all handlers, whether or not written
+ private long ratioChars = 0;
+ private boolean zipBombDetected = false;
- private SecureHandlerCounter(int totalWriteLimit) {
+ private SecureHandlerCounter(int totalWriteLimit, TikaInputStream
rootStream) {
this.totalWriteLimit = totalWriteLimit;
+ this.rootStream = rootStream;
}
/**
* Given the requested length, how many characters are actually
available
@@ -372,6 +385,26 @@ public class RecursiveParserWrapper extends
ParserDecorator {
this.handlerCounter = handlerCounter;
this.throwOnWriteLimitReached = throwOnWriteLimitReached;
this.parseContext = parseContext;
+ OutputLimits limits = OutputLimits.get(parseContext);
+ setOutputThreshold(limits.getZipBombThreshold());
+ setMaximumCompressionRatio(limits.getZipBombRatio());
+ }
+
+ /**
+ * Each embedded document's stream is decompressed, so the per-entry
ratio
+ * can't see archive compression. Also check the whole tree's output
+ * against the container's bytes, as the concatenated path does.
+ */
+ @Override
+ protected void advance(int length) throws SAXException {
+ super.advance(length);
+ handlerCounter.ratioChars += length;
+ try {
+ checkCompressionRatio(handlerCounter.ratioChars,
handlerCounter.rootStream);
+ } catch (SAXException e) {
+ handlerCounter.zipBombDetected = true;
+ throw e;
+ }
}
/**
diff --git
a/tika-core/src/main/java/org/apache/tika/sax/SecureContentHandler.java
b/tika-core/src/main/java/org/apache/tika/sax/SecureContentHandler.java
index d871342774..c0189868c6 100644
--- a/tika-core/src/main/java/org/apache/tika/sax/SecureContentHandler.java
+++ b/tika-core/src/main/java/org/apache/tika/sax/SecureContentHandler.java
@@ -76,7 +76,7 @@ public class SecureContentHandler extends
ContentHandlerDecorator {
/**
* Maximum package entry nesting level.
*/
- private int maxPackageEntryDepth = 10;
+ private int maxPackageEntryDepth = 20;
/**
* Decorates the given content handler with zip bomb prevention based
@@ -103,6 +103,7 @@ public class SecureContentHandler extends
ContentHandlerDecorator {
* @param context the ParseContext (may be null)
* @return a configured SecureContentHandler
*/
+ @SuppressWarnings("removal")
public static SecureContentHandler newInstance(ContentHandler handler,
TikaInputStream stream,
ParseContext context) {
SecureContentHandler sch = new SecureContentHandler(handler, stream);
@@ -181,7 +182,10 @@ public class SecureContentHandler extends
ContentHandlerDecorator {
* Returns the maximum package entry nesting level.
*
* @return maximum package entry nesting level
+ * @deprecated use {@link
org.apache.tika.config.EmbeddedLimits#getMaxDepth()}.
+ * To be removed in 4.3.
*/
+ @Deprecated(since = "4.2", forRemoval = true)
public int getMaximumPackageEntryDepth() {
return maxPackageEntryDepth;
}
@@ -191,7 +195,10 @@ public class SecureContentHandler extends
ContentHandlerDecorator {
* exceeded then an exception gets thrown.
*
* @param depth maximum package entry nesting level
+ * @deprecated use {@link
org.apache.tika.config.EmbeddedLimits#setMaxDepth(int)}.
+ * To be removed in 4.3.
*/
+ @Deprecated(since = "4.2", forRemoval = true)
public void setMaximumPackageEntryDepth(int depth) {
this.maxPackageEntryDepth = depth;
}
@@ -210,7 +217,7 @@ public class SecureContentHandler extends
ContentHandlerDecorator {
}
}
- private long getByteCount() throws SAXException {
+ private static long getByteCount(TikaInputStream stream) throws
SAXException {
try {
//a declared Content-Length is the file's claim; only a measured
length
//or the bytes actually read can serve as the ratio's denominator
@@ -234,8 +241,21 @@ public class SecureContentHandler extends
ContentHandlerDecorator {
*/
protected void advance(int length) throws SAXException {
characterCount += length;
+ checkCompressionRatio(characterCount, stream);
+ }
+
+ /**
+ * Throws if {@code characterCount} exceeds the output threshold and the
maximum
+ * compression ratio against the bytes of {@code source}.
+ *
+ * @param characterCount output characters to check
+ * @param source input stream whose bytes produced them
+ * @throws SAXException if a zip bomb is detected
+ */
+ protected void checkCompressionRatio(long characterCount, TikaInputStream
source)
+ throws SAXException {
if (characterCount > threshold) {
- long byteCount = getByteCount();
+ long byteCount = getByteCount(source);
if (characterCount > byteCount * ratio) {
throw new SecureSAXException("Suspected zip bomb: " +
byteCount + " input bytes produced " + characterCount + " output characters");
}
@@ -253,7 +273,7 @@ public class SecureContentHandler extends
ContentHandlerDecorator {
if ("div".equals(name) &&
"package-entry".equals(atts.getValue("class"))) {
packageEntryDepths.addLast(currentDepth);
- if (packageEntryDepths.size() >= maxPackageEntryDepth) {
+ if (packageEntryDepths.size() > maxPackageEntryDepth) {
throw new SecureSAXException("Suspected zip bomb: " +
packageEntryDepths.size() +
" levels of package entry nesting");
}
diff --git
a/tika-core/src/test/java/org/apache/tika/sax/SecureContentHandlerTest.java
b/tika-core/src/test/java/org/apache/tika/sax/SecureContentHandlerTest.java
index 6a4f624515..32ac2c6e94 100644
--- a/tika-core/src/test/java/org/apache/tika/sax/SecureContentHandlerTest.java
+++ b/tika-core/src/test/java/org/apache/tika/sax/SecureContentHandlerTest.java
@@ -182,7 +182,7 @@ public class SecureContentHandlerTest {
public void testNestedEntries() throws SAXException {
AttributesImpl atts = new AttributesImpl();
atts.addAttribute("", "class", "class", "CDATA", "package-entry");
- for (int i = 1; i < handler.getMaximumPackageEntryDepth(); i++) {
+ for (int i = 1; i <= handler.getMaximumPackageEntryDepth(); i++) {
handler.startElement("", "div", "div", atts);
}
try {
diff --git
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-integration-tests/src/test/java/org/apache/tika/parser/RecursiveParserWrapperTest.java
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-integration-tests/src/test/java/org/apache/tika/parser/RecursiveParserWrapperTest.java
index fb4d30525d..33f1ba5a16 100644
---
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-integration-tests/src/test/java/org/apache/tika/parser/RecursiveParserWrapperTest.java
+++
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-integration-tests/src/test/java/org/apache/tika/parser/RecursiveParserWrapperTest.java
@@ -19,15 +19,19 @@ package org.apache.tika.parser;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
+import java.util.zip.GZIPOutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.ClosedInputStream;
@@ -479,6 +483,25 @@ public class RecursiveParserWrapperTest extends TikaTest {
}
+ @Test
+ public void testCompressionRatioAcrossEmbedded() throws Exception {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ try (GZIPOutputStream gz = new GZIPOutputStream(bos)) {
+ byte[] line = ("a ".repeat(50) +
"\n").getBytes(StandardCharsets.US_ASCII);
+ for (int i = 0; i < 20000; i++) {
+ gz.write(line);
+ }
+ }
+ RecursiveParserWrapper wrapper = new
RecursiveParserWrapper(AUTO_DETECT_PARSER);
+ RecursiveParserWrapperHandler handler = new
RecursiveParserWrapperHandler(
+ new
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.TEXT, -1));
+ try (TikaInputStream tis = TikaInputStream.get(bos.toByteArray())) {
+ TikaException e = assertThrows(TikaException.class,
+ () -> wrapper.parse(tis, handler, new Metadata(), new
ParseContext()));
+ assertTrue(e.getMessage().contains("Zip bomb"));
+ }
+ }
+
private List<Metadata> getMetadata(Metadata metadata,
ContentHandlerFactory
contentHandlerFactory,
boolean catchEmbeddedExceptions,
diff --git
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/test/java/org/apache/tika/parser/pkg/CompressorParserTest.java
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/test/java/org/apache/tika/parser/pkg/CompressorParserTest.java
index d85753d12c..8fd0f56fb7 100644
---
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/test/java/org/apache/tika/parser/pkg/CompressorParserTest.java
+++
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/test/java/org/apache/tika/parser/pkg/CompressorParserTest.java
@@ -41,7 +41,6 @@ import org.xml.sax.helpers.DefaultHandler;
import org.apache.tika.TikaTest;
import org.apache.tika.detect.zip.CompressorConstants;
-import org.apache.tika.exception.TikaException;
import org.apache.tika.io.TikaInputStream;
import org.apache.tika.metadata.HttpHeaders;
import org.apache.tika.metadata.Metadata;
@@ -109,9 +108,8 @@ public class CompressorParserTest extends TikaTest {
CompressorParserTest.class.getResourceAsStream("/test-documents/quine.gz") !=
null);
//https://blog.matthewbarber.io/2019/07/22/how-to-make-compressed-file-quines
- assertThrows(TikaException.class, () -> {
- getXML("quine.gz");
- });
+ assertEquals("true",
+
getXML("quine.gz").metadata.get(TikaCoreProperties.EMBEDDED_DEPTH_LIMIT_REACHED));
}
@Test
diff --git
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/test/java/org/apache/tika/parser/pkg/ZipParserTest.java
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/test/java/org/apache/tika/parser/pkg/ZipParserTest.java
index afae21a842..586d4bc182 100644
---
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/test/java/org/apache/tika/parser/pkg/ZipParserTest.java
+++
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/test/java/org/apache/tika/parser/pkg/ZipParserTest.java
@@ -18,7 +18,6 @@ package org.apache.tika.parser.pkg;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
@@ -35,7 +34,6 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.apache.tika.Tika;
-import org.apache.tika.exception.TikaException;
import org.apache.tika.io.TikaInputStream;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.metadata.TikaCoreProperties;
@@ -157,13 +155,12 @@ public class ZipParserTest extends AbstractPkgTest {
}
@Test
- public void testQuine() {
+ public void testQuine() throws Exception {
//Anti-virus can surreptitiously remove this file
assumeTrue(
ZipParserTest.class.getResourceAsStream("/test-documents/droste.zip") != null);
- assertThrows(TikaException.class, () -> {
- getXML("droste.zip");
- });
+ assertEquals("true",
+
getXML("droste.zip").metadata.get(TikaCoreProperties.EMBEDDED_DEPTH_LIMIT_REACHED));
}
@Test
diff --git
a/tika-serialization/src/test/java/org/apache/tika/config/AllLimitsTest.java
b/tika-serialization/src/test/java/org/apache/tika/config/AllLimitsTest.java
index ff07312d4e..9aae93ddee 100644
--- a/tika-serialization/src/test/java/org/apache/tika/config/AllLimitsTest.java
+++ b/tika-serialization/src/test/java/org/apache/tika/config/AllLimitsTest.java
@@ -143,7 +143,7 @@ public class AllLimitsTest extends TikaTest {
// Helper methods should return defaults when context is null
EmbeddedLimits embeddedLimits = EmbeddedLimits.get(null);
assertNotNull(embeddedLimits);
- assertEquals(EmbeddedLimits.UNLIMITED, embeddedLimits.getMaxDepth());
+ assertEquals(EmbeddedLimits.DEFAULT_MAX_DEPTH,
embeddedLimits.getMaxDepth());
OutputLimits outputLimits = OutputLimits.get(null);
assertNotNull(outputLimits);
diff --git
a/tika-serialization/src/test/java/org/apache/tika/config/EmbeddedLimitsTest.java
b/tika-serialization/src/test/java/org/apache/tika/config/EmbeddedLimitsTest.java
index 4bb4873701..eaead953c2 100644
---
a/tika-serialization/src/test/java/org/apache/tika/config/EmbeddedLimitsTest.java
+++
b/tika-serialization/src/test/java/org/apache/tika/config/EmbeddedLimitsTest.java
@@ -58,7 +58,7 @@ public class EmbeddedLimitsTest extends TikaTest {
@Test
public void testDefaults() {
EmbeddedLimits limits = new EmbeddedLimits();
- assertEquals(EmbeddedLimits.UNLIMITED, limits.getMaxDepth());
+ assertEquals(EmbeddedLimits.DEFAULT_MAX_DEPTH, limits.getMaxDepth());
assertFalse(limits.isThrowOnMaxDepth());
assertEquals(EmbeddedLimits.UNLIMITED, limits.getMaxCount());
assertFalse(limits.isThrowOnMaxCount());
@@ -69,13 +69,13 @@ public class EmbeddedLimitsTest extends TikaTest {
// Test with null context
EmbeddedLimits limits = EmbeddedLimits.get(null);
assertNotNull(limits);
- assertEquals(EmbeddedLimits.UNLIMITED, limits.getMaxDepth());
+ assertEquals(EmbeddedLimits.DEFAULT_MAX_DEPTH, limits.getMaxDepth());
// Test with context that doesn't have EmbeddedLimits
ParseContext context = new ParseContext();
limits = EmbeddedLimits.get(context);
assertNotNull(limits);
- assertEquals(EmbeddedLimits.UNLIMITED, limits.getMaxDepth());
+ assertEquals(EmbeddedLimits.DEFAULT_MAX_DEPTH, limits.getMaxDepth());
// Test with context that has EmbeddedLimits
EmbeddedLimits customLimits = new EmbeddedLimits(10, true, 500, false);
diff --git
a/tika-serialization/src/test/java/org/apache/tika/config/OutputLimitsTest.java
b/tika-serialization/src/test/java/org/apache/tika/config/OutputLimitsTest.java
index 41e23cd570..7a663e97fc 100644
---
a/tika-serialization/src/test/java/org/apache/tika/config/OutputLimitsTest.java
+++
b/tika-serialization/src/test/java/org/apache/tika/config/OutputLimitsTest.java
@@ -65,7 +65,7 @@ public class OutputLimitsTest extends TikaTest {
assertEquals(OutputLimits.UNLIMITED, limits.getWriteLimit());
assertFalse(limits.isThrowOnWriteLimit());
assertEquals(100, limits.getMaxXmlDepth());
- assertEquals(10, limits.getMaxPackageEntryDepth());
+ assertEquals(20, limits.getMaxPackageEntryDepth());
assertEquals(1_000_000, limits.getZipBombThreshold());
assertEquals(100, limits.getZipBombRatio());
}
diff --git
a/tika-serialization/src/test/java/org/apache/tika/config/loader/TikaLoaderTest.java
b/tika-serialization/src/test/java/org/apache/tika/config/loader/TikaLoaderTest.java
index 2e137c87f0..5f14a6d714 100644
---
a/tika-serialization/src/test/java/org/apache/tika/config/loader/TikaLoaderTest.java
+++
b/tika-serialization/src/test/java/org/apache/tika/config/loader/TikaLoaderTest.java
@@ -372,7 +372,7 @@ public class TikaLoaderTest {
// Create defaults - some values will be overridden by JSON, others
kept
EmbeddedLimits defaults = new EmbeddedLimits();
- // Default values from EmbeddedLimits: maxDepth=UNLIMITED,
maxCount=UNLIMITED, throwOnMax*=false
+ // Default values from EmbeddedLimits: maxDepth=DEFAULT_MAX_DEPTH,
maxCount=UNLIMITED, throwOnMax*=false
// Load with defaults - JSON has: maxDepth=5, throwOnMaxDepth=true,
maxCount=100, throwOnMaxCount=false
EmbeddedLimits config = loader.loadConfig(EmbeddedLimits.class,
defaults);
@@ -384,7 +384,7 @@ public class TikaLoaderTest {
assertFalse(config.isThrowOnMaxCount(), "throwOnMaxCount should be
from JSON");
// Verify original defaults object was NOT modified
- assertEquals(EmbeddedLimits.UNLIMITED, defaults.getMaxDepth(),
"Original defaults should be unchanged");
+ assertEquals(EmbeddedLimits.DEFAULT_MAX_DEPTH, defaults.getMaxDepth(),
"Original defaults should be unchanged");
}
@Test