diff --git a/src/ooxml/java/org/apache/poi/ss/usermodel/WorkbookFactory.java b/src/ooxml/java/org/apache/poi/ss/usermodel/WorkbookFactory.java index b6ec1cf8a..bdf37eafc 100644 --- a/src/ooxml/java/org/apache/poi/ss/usermodel/WorkbookFactory.java +++ b/src/ooxml/java/org/apache/poi/ss/usermodel/WorkbookFactory.java @@ -72,30 +72,41 @@ public class WorkbookFactory { */ private static Workbook create(NPOIFSFileSystem fs, String password) throws IOException, InvalidFormatException { DirectoryNode root = fs.getRoot(); + + // Encrypted OOXML files go inside OLE2 containers, is this one? if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) { - if (password == null) { - throw new EncryptedDocumentException("The supplied spreadsheet is protected, but no password was supplied"); - } else { - EncryptionInfo info = new EncryptionInfo(fs); - Decryptor d = Decryptor.getInstance(info); - - boolean passwordCorrect = false; - InputStream stream = null; - try { - if (d.verifyPassword(password)) { - passwordCorrect = true; - stream = d.getDataStream(root); - } - } catch (GeneralSecurityException e) {} - - if (! passwordCorrect) - throw new EncryptedDocumentException("Password incorrect"); - - OPCPackage pkg = OPCPackage.open(stream); - return create(pkg); + EncryptionInfo info = new EncryptionInfo(fs); + Decryptor d = Decryptor.getInstance(info); + + boolean passwordCorrect = false; + InputStream stream = null; + try { + if (password != null && d.verifyPassword(password)) { + passwordCorrect = true; + } + if (!passwordCorrect && d.verifyPassword(Decryptor.DEFAULT_PASSWORD)) { + passwordCorrect = true; + } + if (passwordCorrect) { + stream = d.getDataStream(root); + } + } catch (GeneralSecurityException e) { + throw new IOException(e); } + + 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) { Biff8EncryptionKey.setCurrentUserPassword(password); } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java index 003666958..860031c41 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -1488,27 +1488,33 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { /** * Password Protected .xlsx files should give a helpful - * error message when called via WorkbookFactory. - * (You need to supply a password explicitly for them) + * error message when called via WorkbookFactory with no password */ - @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) public void bug55692_poifs() throws Exception { // Via a POIFSFileSystem - POIFSFileSystem fsP = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx")); + POIFSFileSystem fsP = new POIFSFileSystem( + POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx")); 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 { - // Via a NPOIFSFileSystem - NPOIFSFileSystem fsNP = new NPOIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx")); - WorkbookFactory.create(fsNP); + // Via a NPOIFSFileSystem, will spot it's actually a .xlsx file + // encrypted with the default password, and open + NPOIFSFileSystem fsNP = new NPOIFSFileSystem( + POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx")); + Workbook wb = WorkbookFactory.create(fsNP); + assertNotNull(wb); + assertEquals(3, wb.getNumberOfSheets()); } @Test