This is an automated email from the ASF dual-hosted git repository.

tballison pushed a commit to branch branch_3x
in repository https://gitbox.apache.org/repos/asf/tika.git


The following commit(s) were added to refs/heads/branch_3x by this push:
     new 3341b2eace TIKA-4785 (#2944)
3341b2eace is described below

commit 3341b2eaceca2f772ee5a9eb50842dab553ca65d
Author: Tim Allison <[email protected]>
AuthorDate: Fri Jul 10 14:32:02 2026 -0400

    TIKA-4785 (#2944)
---
 .../org/apache/tika/parser/pkg/PackageParser.java  | 11 +++-
 .../apache/tika/parser/pkg/PackageParserTest.java  | 64 ++++++++++++++++++++++
 2 files changed, 73 insertions(+), 2 deletions(-)

diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/PackageParser.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/PackageParser.java
index 8db2714264..613e7b4432 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/PackageParser.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/PackageParser.java
@@ -449,8 +449,15 @@ public class PackageParser extends 
AbstractEncodingDetectorParser {
                 entry.getSize(), xhtml);
 
         if (extractor.shouldParseEmbedded(entryMetadata)) {
-            try (InputStream entryStream = zipFile.getInputStream(entry)) {
-                extractor.parseEmbedded(entryStream, xhtml, entryMetadata, 
true);
+            // Detectors (e.g. POIFSContainerDetector.isOleHeader) mark/reset 
the stream, but
+            // ZipFile.getInputStream(entry) returns a non-markable 
InflaterInputStream. Wrap it
+            // in a mark/reset-supporting TikaInputStream first, mirroring the 
ArchiveInputStream
+            // path in parseEntry (TIKA-4785). entryStream is closed by the 
try-with-resources;
+            // like parseEntry we don't close the TikaInputStream (that would 
double-close it).
+            try (InputStream entryStream = zipFile.getInputStream(entry);
+                    TemporaryResources tmp = new TemporaryResources()) {
+                TikaInputStream tis = TikaInputStream.get(entryStream, tmp, 
entryMetadata);
+                extractor.parseEmbedded(tis, xhtml, entryMetadata, true);
             } catch (UnsupportedZipFeatureException e) {
                 EmbeddedDocumentUtil.recordEmbeddedStreamException(e, 
parentMetadata);
                 if (name != null && name.length() > 0) {
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pkg/PackageParserTest.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pkg/PackageParserTest.java
index bec188b8d8..f4d7b1efe4 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pkg/PackageParserTest.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pkg/PackageParserTest.java
@@ -16,13 +16,29 @@
  */
 package org.apache.tika.parser.pkg;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
 import java.util.List;
 
 import org.junit.jupiter.api.Test;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.helpers.DefaultHandler;
 
 import org.apache.tika.TikaTest;
+import org.apache.tika.extractor.EmbeddedDocumentExtractor;
+import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
+import org.apache.tika.parser.AutoDetectParser;
+import org.apache.tika.parser.ParseContext;
+import org.apache.tika.parser.Parser;
 
 public class PackageParserTest extends TikaTest {
 
@@ -38,4 +54,52 @@ public class PackageParserTest extends TikaTest {
         assertContains("文章", 
metadataList.get(1).get(TikaCoreProperties.RESOURCE_NAME_KEY));
         assertContains("文章", 
metadataList.get(2).get(TikaCoreProperties.RESOURCE_NAME_KEY));
     }
+
+    /**
+     * TIKA-4785: PackageParser must hand embedded-document extractors a 
mark/reset-supporting
+     * stream. A .sxc (application/vnd.sun.xml.calc) is a zip that 
OpenDocumentParser does not
+     * claim, so it is handled here; the 3.x ZipFile fast-path (parseZipEntry) 
regressed by
+     * passing the raw, non-markable InflaterInputStream from 
ZipFile.getInputStream(entry). A
+     * file-backed input routes through that fast-path. The default extractor 
wraps the stream
+     * defensively, so we install a custom extractor to observe the stream 
Tika hands out.
+     */
+    @Test
+    public void embeddedStreamSupportsMarkReset() throws Exception {
+        List<Boolean> markSupported = new ArrayList<>();
+        Parser parser = new AutoDetectParser();
+        ParseContext context = new ParseContext();
+        context.set(Parser.class, parser);
+        context.set(EmbeddedDocumentExtractor.class, new 
EmbeddedDocumentExtractor() {
+            @Override
+            public boolean shouldParseEmbedded(Metadata metadata) {
+                return true;
+            }
+
+            @Override
+            public void parseEmbedded(InputStream stream, ContentHandler 
handler,
+                                      Metadata metadata, boolean outputHtml) {
+                markSupported.add(stream.markSupported());
+            }
+        });
+
+        Metadata metadata = new Metadata();
+        Path tmpFile = Files.createTempFile("tika4785", ".sxc");
+        try {
+            try (InputStream is =
+                         
getResourceAsStream("/test-documents/testStarOffice-6.0-calc.sxc")) {
+                Files.copy(is, tmpFile, StandardCopyOption.REPLACE_EXISTING);
+            }
+            try (TikaInputStream tis = TikaInputStream.get(tmpFile)) {
+                parser.parse(tis, new DefaultHandler(), metadata, context);
+            }
+        } finally {
+            Files.deleteIfExists(tmpFile);
+        }
+
+        assertEquals("application/vnd.sun.xml.calc", 
metadata.get(Metadata.CONTENT_TYPE));
+        assertFalse(markSupported.isEmpty(), "expected at least one embedded 
entry to be parsed");
+        for (boolean supported : markSupported) {
+            assertTrue(supported, "embedded stream must support mark/reset 
(TIKA-4785)");
+        }
+    }
 }

Reply via email to