private HeaderBlock _header;
private DirectoryNode _root;
- private DataSource _data;
+ protected DataSource _data;
/**
* What big block size the file uses. Most files
_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
*/
--- /dev/null
+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();
+ }
+
+}
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;
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");