Skip to content

Commit 945378a

Browse files
authored
improve hssf parsing (#2874)
1 parent 88a6fc5 commit 945378a

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
@@ -198,24 +198,30 @@ protected void parse(DirectoryNode root, XHTMLContentHandler xhtml, Locale local
198198
}
199199
}
200200

201-
// If a password was supplied, use it, otherwise the default
202-
Biff8EncryptionKey.setCurrentUserPassword(getPassword());
203-
204-
// Have the file processed in event mode
205-
TikaHSSFListener listener =
206-
new TikaHSSFListener(workbookEntryName, xhtml, locale, this, officeParserConfig);
207-
listener.processFile(root, isListenForAllRecords());
208-
listener.throwStoredException();
209-
updateMetadata(listener);
210-
211-
for (Entry entry : root) {
212-
if (entry.getName().startsWith("MBD") && entry instanceof DirectoryEntry) {
213-
try {
214-
handleEmbeddedOfficeDoc((DirectoryEntry) entry, xhtml, true);
215-
} catch (TikaException e) {
216-
// ignore parse errors from embedded documents
201+
// Use the supplied password, otherwise the default. POI keeps it in a ThreadLocal;
202+
// save/restore so it doesn't carry over to the next parse on this thread.
203+
String previousPassword = Biff8EncryptionKey.getCurrentUserPassword();
204+
try {
205+
Biff8EncryptionKey.setCurrentUserPassword(getPassword());
206+
207+
// Have the file processed in event mode
208+
TikaHSSFListener listener =
209+
new TikaHSSFListener(workbookEntryName, xhtml, locale, this, officeParserConfig);
210+
listener.processFile(root, isListenForAllRecords());
211+
listener.throwStoredException();
212+
updateMetadata(listener);
213+
214+
for (Entry entry : root) {
215+
if (entry.getName().startsWith("MBD") && entry instanceof DirectoryEntry) {
216+
try {
217+
handleEmbeddedOfficeDoc((DirectoryEntry) entry, xhtml, true);
218+
} catch (TikaException e) {
219+
// ignore parse errors from embedded documents
220+
}
217221
}
218222
}
223+
} finally {
224+
Biff8EncryptionKey.setCurrentUserPassword(previousPassword);
219225
}
220226
}
221227

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 (TikaInputStream 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 (TikaInputStream 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)