Allow WorkbookFactory.create to open xlsx files protected with the default password

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1676853 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2015-04-29 20:36:13 +00:00
parent 9f196708d4
commit 925d32e2c1
2 changed files with 50 additions and 33 deletions

View File

@ -72,30 +72,41 @@ public class WorkbookFactory {
*/ */
private static Workbook create(NPOIFSFileSystem fs, String password) throws IOException, InvalidFormatException { private static Workbook create(NPOIFSFileSystem fs, String password) throws IOException, InvalidFormatException {
DirectoryNode root = fs.getRoot(); DirectoryNode root = fs.getRoot();
// Encrypted OOXML files go inside OLE2 containers, is this one?
if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) { if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) {
if (password == null) { EncryptionInfo info = new EncryptionInfo(fs);
throw new EncryptedDocumentException("The supplied spreadsheet is protected, but no password was supplied"); Decryptor d = Decryptor.getInstance(info);
} else {
EncryptionInfo info = new EncryptionInfo(fs); boolean passwordCorrect = false;
Decryptor d = Decryptor.getInstance(info); InputStream stream = null;
try {
boolean passwordCorrect = false; if (password != null && d.verifyPassword(password)) {
InputStream stream = null; passwordCorrect = true;
try { }
if (d.verifyPassword(password)) { if (!passwordCorrect && d.verifyPassword(Decryptor.DEFAULT_PASSWORD)) {
passwordCorrect = true; passwordCorrect = true;
stream = d.getDataStream(root); }
} if (passwordCorrect) {
} catch (GeneralSecurityException e) {} stream = d.getDataStream(root);
}
if (! passwordCorrect) } catch (GeneralSecurityException e) {
throw new EncryptedDocumentException("Password incorrect"); throw new IOException(e);
OPCPackage pkg = OPCPackage.open(stream);
return create(pkg);
} }
if (! passwordCorrect) {
if (password != null)
throw new EncryptedDocumentException("Password incorrect");
else
throw new EncryptedDocumentException("The supplied spreadsheet is protected, but no password was supplied");
}
OPCPackage pkg = OPCPackage.open(stream);
return create(pkg);
} }
// If we get here, it isn't an encrypted XLSX file
// So, treat it as a regular HSSF XLS one
if (password != null) { if (password != null) {
Biff8EncryptionKey.setCurrentUserPassword(password); Biff8EncryptionKey.setCurrentUserPassword(password);
} }

View File

@ -1488,27 +1488,33 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
/** /**
* Password Protected .xlsx files should give a helpful * Password Protected .xlsx files should give a helpful
* error message when called via WorkbookFactory. * error message when called via WorkbookFactory with no password
* (You need to supply a password explicitly for them)
*/ */
@Test(expected=EncryptedDocumentException.class)
public void bug55692_stream() throws Exception {
// Directly on a Stream
WorkbookFactory.create(POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
}
@Test(expected=EncryptedDocumentException.class) @Test(expected=EncryptedDocumentException.class)
public void bug55692_poifs() throws Exception { public void bug55692_poifs() throws Exception {
// Via a POIFSFileSystem // Via a POIFSFileSystem
POIFSFileSystem fsP = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx")); POIFSFileSystem fsP = new POIFSFileSystem(
POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
WorkbookFactory.create(fsP); WorkbookFactory.create(fsP);
} }
@Test(expected=EncryptedDocumentException.class) public void bug55692_stream() throws Exception {
// Directly on a Stream, will go via NPOIFS and spot it's
// actually a .xlsx file encrypted with the default password, and open
Workbook wb = WorkbookFactory.create(
POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
assertNotNull(wb);
assertEquals(3, wb.getNumberOfSheets());
}
public void bug55692_npoifs() throws Exception { public void bug55692_npoifs() throws Exception {
// Via a NPOIFSFileSystem // Via a NPOIFSFileSystem, will spot it's actually a .xlsx file
NPOIFSFileSystem fsNP = new NPOIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx")); // encrypted with the default password, and open
WorkbookFactory.create(fsNP); NPOIFSFileSystem fsNP = new NPOIFSFileSystem(
POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
Workbook wb = WorkbookFactory.create(fsNP);
assertNotNull(wb);
assertEquals(3, wb.getNumberOfSheets());
} }
@Test @Test