[bug-63344] add TempFilePOIFSFileSystem

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1857461 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2019-04-13 10:03:02 +00:00
parent fb5d21b1bb
commit bdc3b391fd
3 changed files with 80 additions and 10 deletions

View 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
*/

View File

@ -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();
}
}

View 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");