]> source.dussan.org Git - poi.git/commitdiff
[bug-63344] add TempFilePOIFSFileSystem
authorPJ Fanning <fanningpj@apache.org>
Sat, 13 Apr 2019 10:03:02 +0000 (10:03 +0000)
committerPJ Fanning <fanningpj@apache.org>
Sat, 13 Apr 2019 10:03:02 +0000 (10:03 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1857461 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
src/java/org/apache/poi/poifs/filesystem/TempFilePOIFSFileSystem.java [new file with mode: 0644]
src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java

index afec8a06bad5241f5dbf7e034db27ddc48a23b29..178f6568eef757d34995c2e99681a9c3847687a2 100644 (file)
@@ -87,7 +87,7 @@ public class POIFSFileSystem extends BlockStore
     private HeaderBlock _header;
     private DirectoryNode _root;
 
-    private DataSource _data;
+    protected DataSource _data;
 
     /**
      * What big block size the file uses. Most files
@@ -105,13 +105,17 @@ public class POIFSFileSystem extends BlockStore
         _root = null;
 
         if (newFS) {
-            // Data needs to initially hold just the header block,
-            //  a single bat block, and an empty properties section
-            _data = new ByteArrayBackedDataSource(IOUtils.safelyAllocate(
-                    bigBlockSize.getBigBlockSize() * 3, MAX_RECORD_LENGTH));
+            createNewDataSource();
         }
     }
 
+    protected void createNewDataSource() {
+        // Data needs to initially hold just the header block,
+        //  a single bat block, and an empty properties section
+        _data = new ByteArrayBackedDataSource(IOUtils.safelyAllocate(
+                bigBlockSize.getBigBlockSize() * 3, MAX_RECORD_LENGTH));
+    }
+
     /**
      * Constructor, intended for writing
      */
diff --git a/src/java/org/apache/poi/poifs/filesystem/TempFilePOIFSFileSystem.java b/src/java/org/apache/poi/poifs/filesystem/TempFilePOIFSFileSystem.java
new file mode 100644 (file)
index 0000000..6a7e1f6
--- /dev/null
@@ -0,0 +1,33 @@
+package org.apache.poi.poifs.filesystem;
+
+import org.apache.poi.poifs.nio.FileBackedDataSource;
+import org.apache.poi.util.Beta;
+import org.apache.poi.util.TempFile;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * An experimental POIFSFileSystem to support the encryption of large files
+ *
+ * @since 4.1.1
+ */
+@Beta
+public class TempFilePOIFSFileSystem extends POIFSFileSystem {
+    File tempFile;
+
+    protected void createNewDataSource() {
+        try {
+            tempFile = TempFile.createTempFile("poifs", ".tmp");
+            _data = new FileBackedDataSource(tempFile, false);
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to create data source", e);
+        }
+    }
+
+    public void close() throws IOException {
+        tempFile.delete();
+        super.close();
+    }
+
+}
index f9176187daafd8beeeea7702b504ddbdf3cbb7bd..d7d83ae95a74eea5b89349f39e4b68c6bc06dd0a 100644 (file)
@@ -33,11 +33,7 @@ import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.poifs.crypt.agile.AgileDecryptor;
 import org.apache.poi.poifs.crypt.agile.AgileEncryptionHeader;
 import org.apache.poi.poifs.crypt.agile.AgileEncryptionVerifier;
-import org.apache.poi.poifs.filesystem.DirectoryNode;
-import org.apache.poi.poifs.filesystem.DocumentEntry;
-import org.apache.poi.poifs.filesystem.DocumentNode;
-import org.apache.poi.poifs.filesystem.Entry;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.poifs.filesystem.*;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.TempFile;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
@@ -88,6 +84,43 @@ public class TestEncryptor {
         assertArrayEquals(payloadExpected, payloadActual);
     }
 
+    @Test
+    public void tempFileAgileEncryption() throws Exception {
+        String password = "pass";
+
+        final byte[] payloadExpected;
+        try (InputStream is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("SimpleMultiCell.xlsx")) {
+            payloadExpected = IOUtils.toByteArray(is);
+        }
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        try (POIFSFileSystem fs = new TempFilePOIFSFileSystem()) {
+            EncryptionInfo ei = new EncryptionInfo(EncryptionMode.agile);
+            Encryptor enc = ei.getEncryptor();
+            enc.confirmPassword(password);
+
+            try (OutputStream os = enc.getDataStream(fs.getRoot())) {
+                os.write(payloadExpected);
+            }
+
+            fs.writeFilesystem(bos);
+        }
+
+        final byte[] payloadActual;
+        try (POIFSFileSystem fs = new POIFSFileSystem(new ByteArrayInputStream(bos.toByteArray()))) {
+            EncryptionInfo ei = new EncryptionInfo(fs);
+            Decryptor dec = ei.getDecryptor();
+            boolean b = dec.verifyPassword(password);
+            assertTrue(b);
+
+            try (InputStream is = dec.getDataStream(fs.getRoot())) {
+                payloadActual = IOUtils.toByteArray(is);
+            }
+        }
+
+        assertArrayEquals(payloadExpected, payloadActual);
+    }
+
     @Test
     public void agileEncryption() throws Exception {
         int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES");