1616 */
1717package 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 ;
1928import java .util .List ;
2029
2130import org .junit .jupiter .api .Test ;
31+ import org .xml .sax .ContentHandler ;
32+ import org .xml .sax .helpers .DefaultHandler ;
2233
2334import org .apache .tika .TikaTest ;
35+ import org .apache .tika .extractor .EmbeddedDocumentExtractor ;
36+ import org .apache .tika .io .TikaInputStream ;
2437import org .apache .tika .metadata .Metadata ;
2538import 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
2743public 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