]> source.dussan.org Git - poi.git/commitdiff
Patch from Andreas Beeker from bug #53475 - CSPName may not always be present on...
authorNick Burch <nick@apache.org>
Thu, 7 Nov 2013 21:29:14 +0000 (21:29 +0000)
committerNick Burch <nick@apache.org>
Thu, 7 Nov 2013 21:29:14 +0000 (21:29 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1539828 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/poifs/crypt/EncryptionHeader.java
src/ooxml/testcases/org/apache/poi/xwpf/AllXWPFTests.java
src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFBugs.java [new file with mode: 0644]
test-data/document/bug53475-password-is-solrcell.docx [new file with mode: 0644]

index 9adec4d6ec5aa1ea4467966a34b652f461be3c45..2f10e98edfa48305be785ee001410aa31d299a1f 100644 (file)
 ==================================================================== */
 package org.apache.poi.poifs.crypt;
 
-import org.apache.commons.codec.binary.Base64;
-import org.apache.poi.poifs.filesystem.DocumentInputStream;
-
-import java.io.IOException;
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 
-import org.w3c.dom.NamedNodeMap;
 import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.commons.codec.binary.Base64;
 import org.apache.poi.EncryptedDocumentException;
+import org.apache.poi.poifs.filesystem.DocumentInputStream;
+import org.apache.poi.util.LittleEndianConsts;
+import org.w3c.dom.NamedNodeMap;
 
 /**
  * Reads and processes OOXML Encryption Headers
@@ -69,18 +70,24 @@ public class EncryptionHeader {
 
         is.readLong(); // skip reserved
 
-        StringBuilder builder = new StringBuilder();
-
-        while (true) {
-            char c = (char) is.readShort();
-
-            if (c == 0) {
-                break;
+        // CSPName may not always be specified
+        // In some cases, the sale value of the EncryptionVerifier has the details
+        is.mark(LittleEndianConsts.INT_SIZE+1);
+        int checkForSalt = is.readInt();
+        is.reset();
+        
+        if (checkForSalt == 16) {
+               cspName = "";
+        } else {
+            StringBuilder builder = new StringBuilder();
+            while (true) {
+                char c = (char) is.readShort();
+                if (c == 0) break;
+                builder.append(c);
             }
-
-            builder.append(c);
+            cspName = builder.toString();
         }
-        cspName = builder.toString();
+        
         cipherMode = MODE_ECB;
         keySalt = null;
     }
index b1a9983f75bb95c92f8d877b2f3134faf91ad99a..12b768bba9b2765c763539cab265b04188b6fc79 100644 (file)
@@ -41,6 +41,7 @@ public final class AllXWPFTests {
 
        public static Test suite() {
                TestSuite result = new TestSuite(AllXWPFTests.class.getName());
+               result.addTestSuite(TestXWPFBugs.class);
                result.addTestSuite(TestXWPFDocument.class);
                result.addTestSuite(TestXWPFWordExtractor.class);
                result.addTestSuite(TestXWPFHeaderFooterPolicy.class);
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFBugs.java b/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFBugs.java
new file mode 100644 (file)
index 0000000..d0286f6
--- /dev/null
@@ -0,0 +1,52 @@
+package org.apache.poi.xwpf;\r
+\r
+import java.io.File;\r
+import java.io.InputStream;\r
+\r
+import junit.framework.TestCase;\r
+\r
+import org.apache.poi.POIDataSamples;\r
+import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;\r
+import org.apache.poi.openxml4j.opc.OPCPackage;\r
+import org.apache.poi.poifs.crypt.Decryptor;\r
+import org.apache.poi.poifs.crypt.EncryptionHeader;\r
+import org.apache.poi.poifs.crypt.EncryptionInfo;\r
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;\r
+import org.apache.poi.xwpf.extractor.XWPFWordExtractor;\r
+import org.apache.poi.xwpf.usermodel.XWPFDocument;\r
+\r
+public class TestXWPFBugs extends TestCase {\r
+       /**\r
+        * A word document that's encrypted with non-standard\r
+        *  Encryption options, and no cspname section. See bug 53475\r
+        */\r
+       public void test53475() throws Exception {\r
+               try {\r
+               Biff8EncryptionKey.setCurrentUserPassword("solrcell");\r
+               File file = POIDataSamples.getDocumentInstance().getFile("bug53475-password-is-solrcell.docx");\r
+               NPOIFSFileSystem filesystem = new NPOIFSFileSystem(file, true);\r
+               \r
+               // Check the encryption details\r
+               EncryptionInfo info = new EncryptionInfo(filesystem);\r
+               assertEquals(128, info.getHeader().getKeySize());\r
+               assertEquals(EncryptionHeader.ALGORITHM_AES_128, info.getHeader().getAlgorithm());\r
+               assertEquals(EncryptionHeader.HASH_SHA1, info.getHeader().getHashAlgorithm());\r
+               \r
+               // Check it can be decoded\r
+               Decryptor d = Decryptor.getInstance(info);              \r
+               assertTrue("Unable to process: document is encrypted", d.verifyPassword("solrcell"));\r
+    \r
+               // Check we can read the word document in that\r
+           InputStream dataStream = d.getDataStream(filesystem);\r
+           OPCPackage opc = OPCPackage.open(dataStream);\r
+           XWPFDocument doc = new XWPFDocument(opc);\r
+           XWPFWordExtractor ex = new XWPFWordExtractor(doc);\r
+           String text = ex.getText();\r
+           assertNotNull(text);\r
+           assertEquals("This is password protected Word document.", text.trim());\r
+           ex.close();\r
+               } finally {\r
+                       Biff8EncryptionKey.setCurrentUserPassword(null);\r
+               }\r
+       }\r
+}\r
diff --git a/test-data/document/bug53475-password-is-solrcell.docx b/test-data/document/bug53475-password-is-solrcell.docx
new file mode 100644 (file)
index 0000000..2723d56
Binary files /dev/null and b/test-data/document/bug53475-password-is-solrcell.docx differ