]> source.dussan.org Git - poi.git/commitdiff
Allow WorkbookFactory.create to open xlsx files protected with the default password
authorNick Burch <nick@apache.org>
Wed, 29 Apr 2015 20:36:13 +0000 (20:36 +0000)
committerNick Burch <nick@apache.org>
Wed, 29 Apr 2015 20:36:13 +0000 (20:36 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1676853 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/ss/usermodel/WorkbookFactory.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java

index b6ec1cf8ab0c11db28b2dcc46719edb460d0610f..bdf37eafcac87676388dd2d1329f12f42899c9b5 100644 (file)
@@ -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) 
+            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");
-                
-                OPCPackage pkg = OPCPackage.open(stream);
-                return create(pkg);
+                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);
         }
index 003666958a2957e6f27b3c7e10373d2b93d4290a..860031c4136ec81e085001a67c2177fb40b7c697 100644 (file)
@@ -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