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",

Reply via email to