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 b4c5820c4c TIKA-4985: tika-app -J writes the metadata list when the
container th… (#3379)
b4c5820c4c is described below
commit b4c5820c4c4fd9bc935e8cc30254a84b56c80c72
Author: Tim Allison <[email protected]>
AuthorDate: Wed Oct 21 08:58:17 2026 -0400
TIKA-4985: tika-app -J writes the metadata list when the container th…
(#3379)
* TIKA-4985: tika-app -J writes the metadata list when the container throws
A container exception (zip-bomb trip, corrupt or encrypted file) skipped
the
JSON write, so -J printed nothing. RecursiveParserWrapper has already
recorded
the exception on the first record; write the list as /rmeta does, then
rethrow.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* fix test
---
CHANGES.txt | 5 +++++
.../src/main/java/org/apache/tika/cli/TikaCLI.java | 9 +++++++++
.../test/java/org/apache/tika/cli/TikaCLITest.java | 22 ++++++++++++++++++++++
3 files changed, 36 insertions(+)
diff --git a/CHANGES.txt b/CHANGES.txt
index 819f1a9bcd..8a15e0a123 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -322,6 +322,11 @@ Release 4.2.0 - unreleased
OTHER CHANGES
+ * tika-app -J writes the metadata list when the container throws (a
zip-bomb trip, a
+ corrupt or encrypted file), with the exception in
tk:exception:container-exception on
+ the first record, as /rmeta does; it used to print nothing. The exit
status still
+ reports the failure (TIKA-4985).
+
* A RAR entry junrar fails to extract (truncated archive, bad CRC, missing
password)
is now recorded as tk:exception:embedded-stream-exception on the
container; the
entry still yields what was extracted before the failure, and the rest of
the
diff --git a/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java
b/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java
index 5127226601..299cdcf126 100644
--- a/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java
+++ b/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java
@@ -737,7 +737,16 @@ public class TikaCLI {
RecursiveParserWrapperHandler handler = new
RecursiveParserWrapperHandler(getContentHandlerFactory(type));
try (TikaInputStream tis = TikaInputStream.get(url, metadata)) {
wrapper.parse(tis, handler, metadata, context);
+ } finally {
+ // a container exception is already on the first record: write
what was parsed, as /rmeta does
+ if (!handler.getMetadataList().isEmpty()) {
+ writeRecursiveJson(handler, output);
+ }
}
+ }
+
+ private void writeRecursiveJson(RecursiveParserWrapperHandler handler,
OutputStream output)
+ throws IOException, TikaException {
JsonMetadataList.setPrettyPrinting(prettyPrint);
try (Writer writer = getOutputWriter(output, encoding)) {
List<Metadata> metadataList = handler.getMetadataList();
diff --git a/tika-app/src/test/java/org/apache/tika/cli/TikaCLITest.java
b/tika-app/src/test/java/org/apache/tika/cli/TikaCLITest.java
index 8e3a5d801f..37064bb42b 100644
--- a/tika-app/src/test/java/org/apache/tika/cli/TikaCLITest.java
+++ b/tika-app/src/test/java/org/apache/tika/cli/TikaCLITest.java
@@ -27,6 +27,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
+import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Reader;
import java.net.URI;
@@ -45,6 +46,7 @@ import java.util.HexFormat;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.zip.GZIPOutputStream;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -344,6 +346,26 @@ public class TikaCLITest {
assertTrue(fb > -1 && title > -1 && fb > title);
}
+ @Test
+ public void testJsonRecursiveWritesOnContainerException(@TempDir Path tmp)
throws Exception {
+ // 2.6M chars from a few KB of gzip trips a 100:1 zip-bomb ratio
+ Path config = tmp.resolve("ratio-100.json");
+ Files.writeString(config,
"{\"parse-context\":{\"output-limits\":{\"zipBombRatio\":100}}}");
+ Path gz = tmp.resolve("repetitive.txt.gz");
+ try (OutputStream os = new
GZIPOutputStream(Files.newOutputStream(gz))) {
+ byte[] line = "the same log line, over and over\n".getBytes(UTF_8);
+ for (int i = 0; i < 80_000; i++) {
+ os.write(line);
+ }
+ }
+ resetContent();
+ assertThrows(TikaException.class, () -> TikaCLI.main(new
String[]{"--config=" + config, "-J", gz.toString()}));
+ String json = outContent.toString(UTF_8);
+ assertTrue(json.contains("tk:exception:container-exception"), json);
+ assertTrue(json.contains("Suspected zip bomb"), json);
+ assertTrue(json.contains("the same log line"), json);
+ }
+
@Test
public void testDefaultPDFIncrementalUpdateSettings() throws Exception {
String json = getParamOutContent("-J",