mirror of https://github.com/apache/poi.git
add support for encrypting temp files
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1893435 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3edd698613
commit
803403bc86
|
@ -64,6 +64,7 @@ java {
|
|||
|
||||
dependencies {
|
||||
api project(':poi')
|
||||
//implementation files('/Users/pj.fanning/Downloads/poi-bin-5.1.1-SNAPSHOT/poi-ooxml-lite-5.1.1-SNAPSHOT.jar')
|
||||
api project(':poi-ooxml-full')
|
||||
api project(path: ':poi-ooxml-full', configuration: 'archives')
|
||||
|
||||
|
|
|
@ -17,17 +17,13 @@
|
|||
|
||||
package org.apache.poi.openxml4j.util;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.io.input.UnsynchronizedByteArrayInputStream;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.poi.poifs.crypt.temp.EncryptedTempData;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.util.TempFile;
|
||||
|
||||
|
@ -42,6 +38,7 @@ import org.apache.poi.util.TempFile;
|
|||
private static Logger LOG = LogManager.getLogger(ZipArchiveFakeEntry.class);
|
||||
private byte[] data;
|
||||
private File tempFile;
|
||||
private EncryptedTempData encryptedTempData;
|
||||
|
||||
ZipArchiveFakeEntry(ZipArchiveEntry entry, InputStream inp) throws IOException {
|
||||
super(entry.getName());
|
||||
|
@ -50,10 +47,17 @@ import org.apache.poi.util.TempFile;
|
|||
|
||||
final int threshold = ZipInputStreamZipEntrySource.getThresholdBytesForTempFiles();
|
||||
if (threshold >= 0 && entrySize >= threshold) {
|
||||
tempFile = TempFile.createTempFile("poi-zip-entry", ".tmp");
|
||||
LOG.atInfo().log("created for temp file {} for zip entry {} of size {} bytes",
|
||||
() -> tempFile.getAbsolutePath(), () -> entry.getName(), () -> entrySize);
|
||||
IOUtils.copy(inp, tempFile);
|
||||
if (ZipInputStreamZipEntrySource.shouldEncryptTempFiles()) {
|
||||
encryptedTempData = new EncryptedTempData();
|
||||
try (OutputStream os = encryptedTempData.getOutputStream()) {
|
||||
IOUtils.copy(inp, os);
|
||||
}
|
||||
} else {
|
||||
tempFile = TempFile.createTempFile("poi-zip-entry", ".tmp");
|
||||
LOG.atInfo().log("created for temp file {} for zip entry {} of size {} bytes",
|
||||
() -> tempFile.getAbsolutePath(), () -> entry.getName(), () -> entrySize);
|
||||
IOUtils.copy(inp, tempFile);
|
||||
}
|
||||
} else {
|
||||
if (entrySize < -1 || entrySize >= Integer.MAX_VALUE) {
|
||||
throw new IOException("ZIP entry size is too large or invalid");
|
||||
|
@ -72,7 +76,13 @@ import org.apache.poi.util.TempFile;
|
|||
* @see ZipInputStreamZipEntrySource#setThresholdBytesForTempFiles(int)
|
||||
*/
|
||||
public InputStream getInputStream() {
|
||||
if (tempFile != null) {
|
||||
if (encryptedTempData != null) {
|
||||
try {
|
||||
return encryptedTempData.getInputStream();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("failed to read from encryped temp data", e);
|
||||
}
|
||||
} else if (tempFile != null) {
|
||||
try {
|
||||
return new FileInputStream(tempFile);
|
||||
} catch (FileNotFoundException e) {
|
||||
|
@ -91,6 +101,9 @@ import org.apache.poi.util.TempFile;
|
|||
@Override
|
||||
public void close() throws IOException {
|
||||
data = null;
|
||||
if (encryptedTempData != null) {
|
||||
encryptedTempData.dispose();
|
||||
}
|
||||
if (tempFile != null) {
|
||||
tempFile.delete();
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
|||
*/
|
||||
public class ZipInputStreamZipEntrySource implements ZipEntrySource {
|
||||
private static int thresholdForTempFiles = -1;
|
||||
private static boolean encryptTempFiles = false;
|
||||
private final Map<String, ZipArchiveFakeEntry> zipEntries = new HashMap<>();
|
||||
|
||||
private InputStream streamToClose;
|
||||
|
@ -47,6 +48,7 @@ public class ZipInputStreamZipEntrySource implements ZipEntrySource {
|
|||
* and that zip entries with more than 2GB of data after decompressing will fail, 0 means all
|
||||
* zip entries are stored in temp files. A threshold like 50000000 (approx 50Mb is recommended)
|
||||
* @since POI 5.1.0
|
||||
* @see #setEncryptTempFiles(boolean)
|
||||
*/
|
||||
public static void setThresholdBytesForTempFiles(int thresholdBytes) {
|
||||
thresholdForTempFiles = thresholdBytes;
|
||||
|
@ -62,6 +64,24 @@ public class ZipInputStreamZipEntrySource implements ZipEntrySource {
|
|||
return thresholdForTempFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt temp files when they are used. Only affects temp files related to zip entries.
|
||||
* @param encrypt whether temp files should be encrypted
|
||||
* @since POI 5.1.0
|
||||
* @see #setThresholdBytesForTempFiles(int)
|
||||
*/
|
||||
public static void setEncryptTempFiles(boolean encrypt) {
|
||||
encryptTempFiles = encrypt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether temp files should be encrypted. Only affects temp files related to zip entries.
|
||||
* @since POI 5.1.0
|
||||
*/
|
||||
public static boolean shouldEncryptTempFiles() {
|
||||
return encryptTempFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all the entries from the ZipInputStream
|
||||
* into memory, and don't close (since POI 4.0.1) the source stream.
|
||||
|
|
|
@ -91,7 +91,7 @@ public class EncryptedTempData {
|
|||
*/
|
||||
public void dispose() {
|
||||
if (!tempFile.delete()) {
|
||||
LOG.atWarn().log("{} can't be removed (or was already removed).", tempFile.getAbsolutePath());
|
||||
LOG.atWarn().log("{} can't be removed (or was already removed).", () -> tempFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -188,6 +188,29 @@ public final class TestXSSFWorkbook extends BaseTestXWorkbook {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void existingWithZipEntryEncryptedTempFiles() throws Exception {
|
||||
int defaultThreshold = ZipInputStreamZipEntrySource.getThresholdBytesForTempFiles();
|
||||
boolean defaultEncryptFlag = ZipInputStreamZipEntrySource.shouldEncryptTempFiles();
|
||||
ZipInputStreamZipEntrySource.setEncryptTempFiles(true);
|
||||
ZipInputStreamZipEntrySource.setThresholdBytesForTempFiles(100);
|
||||
try (XSSFWorkbook workbook = openSampleWorkbook("Formatting.xlsx");
|
||||
OPCPackage pkg = OPCPackage.open(openSampleFileStream("Formatting.xlsx"))) {
|
||||
assertNotNull(workbook.getSharedStringSource());
|
||||
assertNotNull(workbook.getStylesSource());
|
||||
|
||||
// And check a few low level bits too
|
||||
PackagePart wbPart = pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml"));
|
||||
|
||||
// Links to the three sheets, shared, styles and themes
|
||||
assertTrue(wbPart.hasRelationships());
|
||||
assertEquals(6, wbPart.getRelationships().size());
|
||||
} finally {
|
||||
ZipInputStreamZipEntrySource.setThresholdBytesForTempFiles(defaultThreshold);
|
||||
ZipInputStreamZipEntrySource.setEncryptTempFiles(defaultEncryptFlag);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCellStyleAt() throws IOException{
|
||||
try (XSSFWorkbook workbook = new XSSFWorkbook()) {
|
||||
|
|
Loading…
Reference in New Issue