Skip to content

Commit 3341b2e

Browse files
authored
1 parent 99dcffc commit 3341b2e

2 files changed

Lines changed: 73 additions & 2 deletions

File tree

  • tika-parsers/tika-parsers-standard
    • tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg
    • tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pkg

tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/PackageParser.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,15 @@ private void parseZipEntry(ZipFile zipFile, ZipArchiveEntry entry,
449449
entry.getSize(), xhtml);
450450

451451
if (extractor.shouldParseEmbedded(entryMetadata)) {
452-
try (InputStream entryStream = zipFile.getInputStream(entry)) {
453-
extractor.parseEmbedded(entryStream, xhtml, entryMetadata, true);
452+
// Detectors (e.g. POIFSContainerDetector.isOleHeader) mark/reset the stream, but
453+
// ZipFile.getInputStream(entry) returns a non-markable InflaterInputStream. Wrap it
454+
// in a mark/reset-supporting TikaInputStream first, mirroring the ArchiveInputStream
455+
// path in parseEntry (TIKA-4785). entryStream is closed by the try-with-resources;
456+
// like parseEntry we don't close the TikaInputStream (that would double-close it).
457+
try (InputStream entryStream = zipFile.getInputStream(entry);
458+
TemporaryResources tmp = new TemporaryResources()) {
459+
TikaInputStream tis = TikaInputStream.get(entryStream, tmp, entryMetadata);
460+
extractor.parseEmbedded(tis, xhtml, entryMetadata, true);
454461
} catch (UnsupportedZipFeatureException e) {
455462
EmbeddedDocumentUtil.recordEmbeddedStreamException(e, parentMetadata);
456463
if (name != null && name.length() > 0) {

tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pkg/PackageParserTest.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,29 @@
1616
*/
1717
package org.apache.tika.parser.pkg;
1818

19+
import static org.junit.jupiter.api.Assertions.assertEquals;
20+
import static org.junit.jupiter.api.Assertions.assertFalse;
21+
import static org.junit.jupiter.api.Assertions.assertTrue;
22+
23+
import java.io.InputStream;
24+
import java.nio.file.Files;
25+
import java.nio.file.Path;
26+
import java.nio.file.StandardCopyOption;
27+
import java.util.ArrayList;
1928
import java.util.List;
2029

2130
import org.junit.jupiter.api.Test;
31+
import org.xml.sax.ContentHandler;
32+
import org.xml.sax.helpers.DefaultHandler;
2233

2334
import org.apache.tika.TikaTest;
35+
import org.apache.tika.extractor.EmbeddedDocumentExtractor;
36+
import org.apache.tika.io.TikaInputStream;
2437
import org.apache.tika.metadata.Metadata;
2538
import org.apache.tika.metadata.TikaCoreProperties;
39+
import org.apache.tika.parser.AutoDetectParser;
40+
import org.apache.tika.parser.ParseContext;
41+
import org.apache.tika.parser.Parser;
2642

2743
public class PackageParserTest extends TikaTest {
2844

@@ -38,4 +54,52 @@ public void handleEntryNameWithCharsetShiftJIS() throws Exception {
3854
assertContains("文章", metadataList.get(1).get(TikaCoreProperties.RESOURCE_NAME_KEY));
3955
assertContains("文章", metadataList.get(2).get(TikaCoreProperties.RESOURCE_NAME_KEY));
4056
}
57+
58+
/**
59+
* TIKA-4785: PackageParser must hand embedded-document extractors a mark/reset-supporting
60+
* stream. A .sxc (application/vnd.sun.xml.calc) is a zip that OpenDocumentParser does not
61+
* claim, so it is handled here; the 3.x ZipFile fast-path (parseZipEntry) regressed by
62+
* passing the raw, non-markable InflaterInputStream from ZipFile.getInputStream(entry). A
63+
* file-backed input routes through that fast-path. The default extractor wraps the stream
64+
* defensively, so we install a custom extractor to observe the stream Tika hands out.
65+
*/
66+
@Test
67+
public void embeddedStreamSupportsMarkReset() throws Exception {
68+
List<Boolean> markSupported = new ArrayList<>();
69+
Parser parser = new AutoDetectParser();
70+
ParseContext context = new ParseContext();
71+
context.set(Parser.class, parser);
72+
context.set(EmbeddedDocumentExtractor.class, new EmbeddedDocumentExtractor() {
73+
@Override
74+
public boolean shouldParseEmbedded(Metadata metadata) {
75+
return true;
76+
}
77+
78+
@Override
79+
public void parseEmbedded(InputStream stream, ContentHandler handler,
80+
Metadata metadata, boolean outputHtml) {
81+
markSupported.add(stream.markSupported());
82+
}
83+
});
84+
85+
Metadata metadata = new Metadata();
86+
Path tmpFile = Files.createTempFile("tika4785", ".sxc");
87+
try {
88+
try (InputStream is =
89+
getResourceAsStream("/test-documents/testStarOffice-6.0-calc.sxc")) {
90+
Files.copy(is, tmpFile, StandardCopyOption.REPLACE_EXISTING);
91+
}
92+
try (TikaInputStream tis = TikaInputStream.get(tmpFile)) {
93+
parser.parse(tis, new DefaultHandler(), metadata, context);
94+
}
95+
} finally {
96+
Files.deleteIfExists(tmpFile);
97+
}
98+
99+
assertEquals("application/vnd.sun.xml.calc", metadata.get(Metadata.CONTENT_TYPE));
100+
assertFalse(markSupported.isEmpty(), "expected at least one embedded entry to be parsed");
101+
for (boolean supported : markSupported) {
102+
assertTrue(supported, "embedded stream must support mark/reset (TIKA-4785)");
103+
}
104+
}
41105
}

0 commit comments

Comments
 (0)