Skip to content

Commit fce8805

Browse files
committed
improve hssf parsing
1 parent 316edce commit fce8805

2 files changed

Lines changed: 52 additions & 16 deletions

File tree

  • tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src

tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/ExcelExtractor.java

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -188,24 +188,30 @@ protected void parse(DirectoryNode root, XHTMLContentHandler xhtml, Locale local
188188
}
189189
}
190190

191-
// If a password was supplied, use it, otherwise the default
192-
Biff8EncryptionKey.setCurrentUserPassword(getPassword());
193-
194-
// Have the file processed in event mode
195-
TikaHSSFListener listener =
196-
new TikaHSSFListener(workbookEntryName, xhtml, locale, this, officeParserConfig);
197-
listener.processFile(root, isListenForAllRecords());
198-
listener.throwStoredException();
199-
updateMetadata(listener);
200-
201-
for (Entry entry : root) {
202-
if (entry.getName().startsWith("MBD") && entry instanceof DirectoryEntry) {
203-
try {
204-
handleEmbeddedOfficeDoc((DirectoryEntry) entry, xhtml, true);
205-
} catch (TikaException e) {
206-
// ignore parse errors from embedded documents
191+
// Use the supplied password, otherwise the default. POI keeps it in a ThreadLocal;
192+
// save/restore so it doesn't carry over to the next parse on this thread.
193+
String previousPassword = Biff8EncryptionKey.getCurrentUserPassword();
194+
try {
195+
Biff8EncryptionKey.setCurrentUserPassword(getPassword());
196+
197+
// Have the file processed in event mode
198+
TikaHSSFListener listener =
199+
new TikaHSSFListener(workbookEntryName, xhtml, locale, this, officeParserConfig);
200+
listener.processFile(root, isListenForAllRecords());
201+
listener.throwStoredException();
202+
updateMetadata(listener);
203+
204+
for (Entry entry : root) {
205+
if (entry.getName().startsWith("MBD") && entry instanceof DirectoryEntry) {
206+
try {
207+
handleEmbeddedOfficeDoc((DirectoryEntry) entry, xhtml, true);
208+
} catch (TikaException e) {
209+
// ignore parse errors from embedded documents
210+
}
207211
}
208212
}
213+
} finally {
214+
Biff8EncryptionKey.setCurrentUserPassword(previousPassword);
209215
}
210216
}
211217

tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/ExcelParserTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
import java.text.DecimalFormatSymbols;
2626
import java.util.List;
2727
import java.util.Locale;
28+
import java.util.UUID;
2829

30+
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
2931
import org.apache.poi.util.LocaleUtil;
3032
import org.junit.jupiter.api.Test;
3133
import org.xml.sax.ContentHandler;
@@ -210,6 +212,34 @@ public String getPassword(Metadata metadata) {
210212
}
211213
}
212214

215+
@Test
216+
public void testPasswordThreadLocalRestored() throws Exception {
217+
String sentinel = "sentinel-" + UUID.randomUUID();
218+
String original = Biff8EncryptionKey.getCurrentUserPassword();
219+
try {
220+
Biff8EncryptionKey.setCurrentUserPassword(sentinel);
221+
222+
try (InputStream tis = getResourceAsStream(
223+
"/test-documents/testEXCEL_protected_passtika.xls")) {
224+
ParseContext context = new ParseContext();
225+
context.set(PasswordProvider.class, metadata -> "tika");
226+
new OfficeParser().parse(tis, new BodyContentHandler(), new Metadata(), context);
227+
}
228+
assertEquals(sentinel, Biff8EncryptionKey.getCurrentUserPassword());
229+
230+
try (InputStream tis = getResourceAsStream(
231+
"/test-documents/testEXCEL_protected_passtika.xls")) {
232+
new OfficeParser().parse(tis, new BodyContentHandler(), new Metadata(),
233+
new ParseContext());
234+
fail("Document is encrypted, shouldn't parse");
235+
} catch (EncryptedDocumentException e) {
236+
assertEquals(sentinel, Biff8EncryptionKey.getCurrentUserPassword());
237+
}
238+
} finally {
239+
Biff8EncryptionKey.setCurrentUserPassword(original);
240+
}
241+
}
242+
213243
/**
214244
* TIKA-214 - Ensure we extract labels etc from Charts
215245
*/

0 commit comments

Comments
 (0)