ASF Bugzilla – Attachment 34284 Details for
Bug 60153
[PATCH] Use ZipEntrySource in SXSSF module
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
[PATCH] open up SXSSF classes so that they can be subclassed
patch.txt (text/plain), 25.12 KB, created by
PJ Fanning
on 2016-09-20 23:23:57 UTC
(
hide
)
Description:
[PATCH] open up SXSSF classes so that they can be subclassed
Filename:
MIME Type:
Creator:
PJ Fanning
Created:
2016-09-20 23:23:57 UTC
Size:
25.12 KB
patch
obsolete
>From 72f0ada28f17b0079d296fa6dbc98d3b76b058a3 Mon Sep 17 00:00:00 2001 >From: PJ Fanning <pj.fanning@workday.com> >Date: Tue, 20 Sep 2016 22:37:31 +0100 >Subject: [PATCH] allow decorators to be used in SheetDataWriter and use > ZipEntrySource in SXSSFWorkbook to allow custom implementations to be used > instead of raw ZipFile > >--- > .../org/apache/poi/xssf/streaming/SXSSFWorkbook.java | 18 +++++++++--------- > .../org/apache/poi/xssf/streaming/SheetDataWriter.java | 15 ++++++++++++--- > 2 files changed, 21 insertions(+), 12 deletions(-) > >diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java >index 331ad9a..23032c6 100644 >--- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java >+++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java >@@ -35,6 +35,8 @@ import java.util.zip.ZipFile; > import java.util.zip.ZipOutputStream; > > import org.apache.poi.openxml4j.opc.OPCPackage; >+import org.apache.poi.openxml4j.util.ZipEntrySource; >+import org.apache.poi.openxml4j.util.ZipFileZipEntrySource; > import org.apache.poi.ss.SpreadsheetVersion; > import org.apache.poi.ss.formula.udf.UDFFinder; > import org.apache.poi.ss.usermodel.CellStyle; >@@ -101,12 +103,12 @@ public class SXSSFWorkbook implements Workbook { > /** > * whether temp files should be compressed. > */ >- private boolean _compressTmpFiles = false; >+ protected boolean _compressTmpFiles = false; > > /** > * shared string table - a cache of strings in this workbook > */ >- private final SharedStringsTable _sharedStringSource; >+ protected final SharedStringsTable _sharedStringSource; > > /** > * Construct a new workbook with default row window size >@@ -353,21 +355,19 @@ public class SXSSFWorkbook implements Workbook { > return null; > } > >- private void injectData(File zipfile, OutputStream out) throws IOException >+ private void injectData(ZipEntrySource zipEntrySource, OutputStream out) throws IOException > { >- // don't use ZipHelper.openZipFile here - see #59743 >- ZipFile zip = new ZipFile(zipfile); > try > { > ZipOutputStream zos = new ZipOutputStream(out); > try > { >- Enumeration<? extends ZipEntry> en = zip.entries(); >+ Enumeration<? extends ZipEntry> en = zipEntrySource.getEntries(); > while (en.hasMoreElements()) > { > ZipEntry ze = en.nextElement(); > zos.putNextEntry(new ZipEntry(ze.getName())); >- InputStream is = zip.getInputStream(ze); >+ InputStream is = zipEntrySource.getInputStream(ze); > XSSFSheet xSheet=getSheetFromZipEntryName(ze.getName()); > if(xSheet!=null) > { >@@ -396,7 +396,7 @@ public class SXSSFWorkbook implements Workbook { > } > finally > { >- zip.close(); >+ zipEntrySource.close(); > } > } > private static void copyStream(InputStream in, OutputStream out) throws IOException { >@@ -946,7 +946,7 @@ public class SXSSFWorkbook implements Workbook { > } > > //Substitute the template entries with the generated sheet data files >- injectData(tmplFile, stream); >+ injectData(new ZipFileZipEntrySource(new ZipFile(tmplFile)), stream); > } > finally > { >diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java >index 4bd0c6b..54c6f4f 100644 >--- a/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java >+++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java >@@ -25,6 +25,7 @@ import java.io.FileInputStream; > import java.io.FileOutputStream; > import java.io.IOException; > import java.io.InputStream; >+import java.io.OutputStream; > import java.io.OutputStreamWriter; > import java.io.Writer; > import java.util.Iterator; >@@ -90,8 +91,12 @@ public class SheetDataWriter { > * > * @param fd the file to write to > */ >- public Writer createWriter(File fd)throws IOException { >- return new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fd), "UTF-8")); >+ public Writer createWriter(File fd) throws IOException { >+ return new BufferedWriter(new OutputStreamWriter(decorateOutputStream(new FileOutputStream(fd)), "UTF-8")); >+ } >+ >+ protected OutputStream decorateOutputStream(FileOutputStream fos) { >+ return fos; > } > > /** >@@ -112,7 +117,11 @@ public class SheetDataWriter { > */ > public InputStream getWorksheetXMLInputStream() throws IOException { > File fd = getTempFile(); >- return new FileInputStream(fd); >+ return decorateInputStream(new FileInputStream(fd)); >+ } >+ >+ protected InputStream decorateInputStream(FileInputStream fis) { >+ return fis; > } > > public int getNumberOfFlushedRows() { >-- >2.2.1 > >From 333d1af99908a42394608feb8d462ebae99efc7e Mon Sep 17 00:00:00 2001 >From: PJ Fanning <pj.fanning@workday.com> >Date: Wed, 21 Sep 2016 00:10:06 +0100 >Subject: [PATCH] add test case for encrypting temp file data > >--- > .../apache/poi/xssf/streaming/SXSSFWorkbook.java | 18 +-- > .../poi/poifs/crypt/AesZipFileZipEntrySource.java | 118 +++++++++++++++++ > .../apache/poi/poifs/crypt/TestSecureTempZip.java | 106 +--------------- > .../TestSXSSFWorkbookWithCustomZipEntrySource.java | 140 +++++++++++++++++++++ > 4 files changed, 270 insertions(+), 112 deletions(-) > create mode 100644 src/ooxml/testcases/org/apache/poi/poifs/crypt/AesZipFileZipEntrySource.java > create mode 100644 src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbookWithCustomZipEntrySource.java > >diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java >index 23032c6..82768ae 100644 >--- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java >+++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java >@@ -93,7 +93,7 @@ public class SXSSFWorkbook implements Workbook { > public static final int DEFAULT_WINDOW_SIZE = 100; > private static final POILogger logger = POILogFactory.getLogger(SXSSFWorkbook.class); > >- private final XSSFWorkbook _wb; >+ protected final XSSFWorkbook _wb; > > private final Map<SXSSFSheet,XSSFSheet> _sxFromXHash = new HashMap<SXSSFSheet,XSSFSheet>(); > private final Map<XSSFSheet,SXSSFSheet> _xFromSxHash = new HashMap<XSSFSheet,SXSSFSheet>(); >@@ -306,7 +306,7 @@ public class SXSSFWorkbook implements Workbook { > _compressTmpFiles = compress; > } > >- SheetDataWriter createSheetDataWriter() throws IOException { >+ protected SheetDataWriter createSheetDataWriter() throws IOException { > if(_compressTmpFiles) { > return new GZIPSheetDataWriter(_sharedStringSource); > } >@@ -355,7 +355,7 @@ public class SXSSFWorkbook implements Workbook { > return null; > } > >- private void injectData(ZipEntrySource zipEntrySource, OutputStream out) throws IOException >+ protected void injectData(ZipEntrySource zipEntrySource, OutputStream out) throws IOException > { > try > { >@@ -926,10 +926,7 @@ public class SXSSFWorkbook implements Workbook { > @Override > public void write(OutputStream stream) throws IOException > { >- for (SXSSFSheet sheet : _xFromSxHash.values()) >- { >- sheet.flushRows(); >- } >+ flushSheets(); > > //Save the template > File tmplFile = TempFile.createTempFile("poi-sxssf-template", ".xlsx"); >@@ -956,6 +953,13 @@ public class SXSSFWorkbook implements Workbook { > } > } > >+ protected void flushSheets() throws IOException { >+ for (SXSSFSheet sheet : _xFromSxHash.values()) >+ { >+ sheet.flushRows(); >+ } >+ } >+ > /** > * Dispose of temporary files backing this workbook on disk. > * Calling this method will render the workbook unusable. >diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/AesZipFileZipEntrySource.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/AesZipFileZipEntrySource.java >new file mode 100644 >index 0000000..fd15cfd >--- /dev/null >+++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/AesZipFileZipEntrySource.java >@@ -0,0 +1,118 @@ >+package org.apache.poi.poifs.crypt; >+ >+import java.io.File; >+import java.io.FileOutputStream; >+import java.io.FilterOutputStream; >+import java.io.IOException; >+import java.io.InputStream; >+import java.security.GeneralSecurityException; >+import java.security.SecureRandom; >+import java.util.Enumeration; >+import java.util.zip.ZipEntry; >+import java.util.zip.ZipException; >+import java.util.zip.ZipFile; >+import java.util.zip.ZipInputStream; >+import java.util.zip.ZipOutputStream; >+ >+import javax.crypto.Cipher; >+import javax.crypto.CipherInputStream; >+import javax.crypto.CipherOutputStream; >+import javax.crypto.spec.SecretKeySpec; >+ >+import org.apache.poi.openxml4j.util.ZipEntrySource; >+import org.apache.poi.util.IOUtils; >+import org.apache.poi.util.TempFile; >+ >+public class AesZipFileZipEntrySource implements ZipEntrySource { >+ final File tmpFile; >+ final ZipFile zipFile; >+ final Cipher ci; >+ boolean closed; >+ >+ public AesZipFileZipEntrySource(File tmpFile, Cipher ci) throws IOException { >+ this.tmpFile = tmpFile; >+ this.zipFile = new ZipFile(tmpFile); >+ this.ci = ci; >+ this.closed = false; >+ } >+ >+ /** >+ * Note: the file sizes are rounded up to the next cipher block size, >+ * so don't rely on file sizes of these custom encrypted zip file entries! >+ */ >+ public Enumeration<? extends ZipEntry> getEntries() { >+ return zipFile.entries(); >+ } >+ >+ @SuppressWarnings("resource") >+ public InputStream getInputStream(ZipEntry entry) throws IOException { >+ InputStream is = zipFile.getInputStream(entry); >+ return new CipherInputStream(is, ci); >+ } >+ >+ @Override >+ public void close() throws IOException { >+ zipFile.close(); >+ tmpFile.delete(); >+ closed = true; >+ } >+ >+ @Override >+ public boolean isClosed() { >+ return closed; >+ } >+ >+ public static ZipEntrySource createZipEntrySource(InputStream is) throws IOException, GeneralSecurityException { >+ // generate session key >+ SecureRandom sr = new SecureRandom(); >+ byte[] ivBytes = new byte[16], keyBytes = new byte[16]; >+ sr.nextBytes(ivBytes); >+ sr.nextBytes(keyBytes); >+ final File tmpFile = TempFile.createTempFile("protectedXlsx", ".zip"); >+ copyToFile(is, tmpFile, CipherAlgorithm.aes128, keyBytes, ivBytes); >+ IOUtils.closeQuietly(is); >+ return fileToSource(tmpFile, CipherAlgorithm.aes128, keyBytes, ivBytes); >+ } >+ >+ private static void copyToFile(InputStream is, File tmpFile, CipherAlgorithm cipherAlgorithm, byte keyBytes[], byte ivBytes[]) throws IOException, GeneralSecurityException { >+ SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, cipherAlgorithm.jceId); >+ Cipher ciEnc = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.ENCRYPT_MODE, "PKCS5Padding"); >+ >+ ZipInputStream zis = new ZipInputStream(is); >+ FileOutputStream fos = new FileOutputStream(tmpFile); >+ ZipOutputStream zos = new ZipOutputStream(fos); >+ >+ ZipEntry ze; >+ while ((ze = zis.getNextEntry()) != null) { >+ // the cipher output stream pads the data, therefore we can't reuse the ZipEntry with set sizes >+ // as those will be validated upon close() >+ ZipEntry zeNew = new ZipEntry(ze.getName()); >+ zeNew.setComment(ze.getComment()); >+ zeNew.setExtra(ze.getExtra()); >+ zeNew.setTime(ze.getTime()); >+ // zeNew.setMethod(ze.getMethod()); >+ zos.putNextEntry(zeNew); >+ FilterOutputStream fos2 = new FilterOutputStream(zos){ >+ // don't close underlying ZipOutputStream >+ public void close() {} >+ }; >+ CipherOutputStream cos = new CipherOutputStream(fos2, ciEnc); >+ IOUtils.copy(zis, cos); >+ cos.close(); >+ fos2.close(); >+ zos.closeEntry(); >+ zis.closeEntry(); >+ } >+ zos.close(); >+ fos.close(); >+ zis.close(); >+ } >+ >+ private static ZipEntrySource fileToSource(File tmpFile, CipherAlgorithm cipherAlgorithm, byte keyBytes[], byte ivBytes[]) throws ZipException, IOException { >+ SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, cipherAlgorithm.jceId); >+ Cipher ciDec = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.DECRYPT_MODE, "PKCS5Padding"); >+ return new AesZipFileZipEntrySource(tmpFile, ciDec); >+ } >+ >+} >+ >diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSecureTempZip.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSecureTempZip.java >index 868a382..77ae003 100644 >--- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSecureTempZip.java >+++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSecureTempZip.java >@@ -22,30 +22,14 @@ import static org.junit.Assert.assertTrue; > > import java.io.File; > import java.io.FileInputStream; >-import java.io.FileOutputStream; >-import java.io.FilterOutputStream; > import java.io.IOException; > import java.io.InputStream; > import java.security.GeneralSecurityException; >-import java.security.SecureRandom; >-import java.util.Enumeration; >-import java.util.zip.ZipEntry; >-import java.util.zip.ZipException; >-import java.util.zip.ZipFile; >-import java.util.zip.ZipInputStream; >-import java.util.zip.ZipOutputStream; >- >-import javax.crypto.Cipher; >-import javax.crypto.CipherInputStream; >-import javax.crypto.CipherOutputStream; >-import javax.crypto.spec.SecretKeySpec; > > import org.apache.poi.openxml4j.exceptions.OpenXML4JException; > import org.apache.poi.openxml4j.opc.OPCPackage; > import org.apache.poi.openxml4j.util.ZipEntrySource; > import org.apache.poi.poifs.filesystem.POIFSFileSystem; >-import org.apache.poi.util.IOUtils; >-import org.apache.poi.util.TempFile; > import org.apache.poi.xssf.XSSFTestDataSamples; > import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor; > import org.apache.poi.xssf.usermodel.XSSFWorkbook; >@@ -59,7 +43,6 @@ public class TestSecureTempZip { > */ > @Test > public void protectedTempZip() throws IOException, GeneralSecurityException, XmlException, OpenXML4JException { >- final File tmpFile = TempFile.createTempFile("protectedXlsx", ".zip"); > File tikaProt = XSSFTestDataSamples.getSampleFile("protected_passtika.xlsx"); > FileInputStream fis = new FileInputStream(tikaProt); > POIFSFileSystem poifs = new POIFSFileSystem(fis); >@@ -68,19 +51,11 @@ public class TestSecureTempZip { > boolean passOk = dec.verifyPassword("tika"); > assertTrue(passOk); > >- // generate session key >- SecureRandom sr = new SecureRandom(); >- byte[] ivBytes = new byte[16], keyBytes = new byte[16]; >- sr.nextBytes(ivBytes); >- sr.nextBytes(keyBytes); >- > // extract encrypted ooxml file and write to custom encrypted zip file > InputStream is = dec.getDataStream(poifs); >- copyToFile(is, tmpFile, CipherAlgorithm.aes128, keyBytes, ivBytes); >- is.close(); > > // provide ZipEntrySource to poi which decrypts on the fly >- ZipEntrySource source = fileToSource(tmpFile, CipherAlgorithm.aes128, keyBytes, ivBytes); >+ ZipEntrySource source = AesZipFileZipEntrySource.createZipEntrySource(is); > > // test the source > OPCPackage opc = OPCPackage.open(source); >@@ -102,84 +77,5 @@ public class TestSecureTempZip { > source.close(); > poifs.close(); > fis.close(); >- tmpFile.delete(); >- } >- >- private void copyToFile(InputStream is, File tmpFile, CipherAlgorithm cipherAlgorithm, byte keyBytes[], byte ivBytes[]) throws IOException, GeneralSecurityException { >- SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, cipherAlgorithm.jceId); >- Cipher ciEnc = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.ENCRYPT_MODE, "PKCS5Padding"); >- >- ZipInputStream zis = new ZipInputStream(is); >- FileOutputStream fos = new FileOutputStream(tmpFile); >- ZipOutputStream zos = new ZipOutputStream(fos); >- >- ZipEntry ze; >- while ((ze = zis.getNextEntry()) != null) { >- // the cipher output stream pads the data, therefore we can't reuse the ZipEntry with set sizes >- // as those will be validated upon close() >- ZipEntry zeNew = new ZipEntry(ze.getName()); >- zeNew.setComment(ze.getComment()); >- zeNew.setExtra(ze.getExtra()); >- zeNew.setTime(ze.getTime()); >- // zeNew.setMethod(ze.getMethod()); >- zos.putNextEntry(zeNew); >- FilterOutputStream fos2 = new FilterOutputStream(zos){ >- // don't close underlying ZipOutputStream >- public void close() {} >- }; >- CipherOutputStream cos = new CipherOutputStream(fos2, ciEnc); >- IOUtils.copy(zis, cos); >- cos.close(); >- fos2.close(); >- zos.closeEntry(); >- zis.closeEntry(); >- } >- zos.close(); >- fos.close(); >- zis.close(); >- } >- >- private ZipEntrySource fileToSource(File tmpFile, CipherAlgorithm cipherAlgorithm, byte keyBytes[], byte ivBytes[]) throws ZipException, IOException { >- SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, cipherAlgorithm.jceId); >- Cipher ciDec = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.DECRYPT_MODE, "PKCS5Padding"); >- ZipFile zf = new ZipFile(tmpFile); >- return new AesZipFileZipEntrySource(zf, ciDec); >- } >- >- static class AesZipFileZipEntrySource implements ZipEntrySource { >- final ZipFile zipFile; >- final Cipher ci; >- boolean closed; >- >- AesZipFileZipEntrySource(ZipFile zipFile, Cipher ci) { >- this.zipFile = zipFile; >- this.ci = ci; >- this.closed = false; >- } >- >- /** >- * Note: the file sizes are rounded up to the next cipher block size, >- * so don't rely on file sizes of these custom encrypted zip file entries! >- */ >- public Enumeration<? extends ZipEntry> getEntries() { >- return zipFile.entries(); >- } >- >- @SuppressWarnings("resource") >- public InputStream getInputStream(ZipEntry entry) throws IOException { >- InputStream is = zipFile.getInputStream(entry); >- return new CipherInputStream(is, ci); >- } >- >- @Override >- public void close() throws IOException { >- zipFile.close(); >- closed = true; >- } >- >- @Override >- public boolean isClosed() { >- return closed; >- } > } > } >diff --git a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbookWithCustomZipEntrySource.java b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbookWithCustomZipEntrySource.java >new file mode 100644 >index 0000000..4831b74 >--- /dev/null >+++ b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbookWithCustomZipEntrySource.java >@@ -0,0 +1,140 @@ >+/* >+ * ==================================================================== >+ * Licensed to the Apache Software Foundation (ASF) under one or more >+ * contributor license agreements. See the NOTICE file distributed with >+ * this work for additional information regarding copyright ownership. >+ * The ASF licenses this file to You under the Apache License, Version 2.0 >+ * (the "License"); you may not use this file except in compliance with >+ * the License. You may obtain a copy of the License at >+ * >+ * http://www.apache.org/licenses/LICENSE-2.0 >+ * >+ * Unless required by applicable law or agreed to in writing, software >+ * distributed under the License is distributed on an "AS IS" BASIS, >+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ * ==================================================================== >+ */ >+ >+package org.apache.poi.xssf.streaming; >+ >+import static org.junit.Assert.assertEquals; >+ >+import java.io.ByteArrayInputStream; >+import java.io.ByteArrayOutputStream; >+import java.io.FileInputStream; >+import java.io.FileOutputStream; >+import java.io.IOException; >+import java.io.InputStream; >+import java.io.OutputStream; >+import java.security.GeneralSecurityException; >+import java.security.SecureRandom; >+ >+import javax.crypto.Cipher; >+import javax.crypto.CipherInputStream; >+import javax.crypto.CipherOutputStream; >+import javax.crypto.spec.SecretKeySpec; >+ >+import org.apache.poi.openxml4j.util.ZipEntrySource; >+import org.apache.poi.poifs.crypt.AesZipFileZipEntrySource; >+import org.apache.poi.poifs.crypt.ChainingMode; >+import org.apache.poi.poifs.crypt.CipherAlgorithm; >+import org.apache.poi.poifs.crypt.CryptoFunctions; >+import org.apache.poi.util.POILogFactory; >+import org.apache.poi.util.POILogger; >+import org.apache.poi.xssf.usermodel.XSSFCell; >+import org.apache.poi.xssf.usermodel.XSSFRow; >+import org.apache.poi.xssf.usermodel.XSSFSheet; >+import org.apache.poi.xssf.usermodel.XSSFWorkbook; >+import org.junit.Test; >+ >+public final class TestSXSSFWorkbookWithCustomZipEntrySource { >+ >+ @Test >+ public void customZipEntrySource() throws IOException, GeneralSecurityException { >+ final String sheetName = "TestSheet1"; >+ final String cellValue = "customZipEntrySource"; >+ SXSSFWorkbookWithCustomZipEntrySource workbook = new SXSSFWorkbookWithCustomZipEntrySource(); >+ SXSSFSheet sheet1 = workbook.createSheet(sheetName); >+ SXSSFRow row1 = sheet1.createRow(1); >+ SXSSFCell cell1 = row1.createCell(1); >+ cell1.setCellValue("customZipEntrySource"); >+ ByteArrayOutputStream os = new ByteArrayOutputStream(); >+ workbook.write(os); >+ workbook.close(); >+ workbook.dispose(); >+ XSSFWorkbook xwb = new XSSFWorkbook(new ByteArrayInputStream(os.toByteArray())); >+ XSSFSheet xs1 = xwb.getSheetAt(0); >+ assertEquals(sheetName, xs1.getSheetName()); >+ XSSFRow xr1 = xs1.getRow(1); >+ XSSFCell xc1 = xr1.getCell(1); >+ assertEquals(cellValue, xc1.getStringCellValue()); >+ xwb.close(); >+ } >+ >+ static class SXSSFWorkbookWithCustomZipEntrySource extends SXSSFWorkbook { >+ >+ private static final POILogger logger = POILogFactory.getLogger(SXSSFWorkbookWithCustomZipEntrySource.class); >+ >+ @Override >+ public void write(OutputStream stream) throws IOException { >+ flushSheets(); >+ ByteArrayOutputStream os = new ByteArrayOutputStream(); >+ _wb.write(os); >+ ZipEntrySource source = null; >+ try { >+ // provide ZipEntrySource to poi which decrypts on the fly >+ source = AesZipFileZipEntrySource.createZipEntrySource(new ByteArrayInputStream(os.toByteArray())); >+ injectData(source, stream); >+ } catch (GeneralSecurityException e) { >+ throw new IOException(e); >+ } finally { >+ source.close(); >+ } >+ } >+ >+ @Override >+ protected SheetDataWriter createSheetDataWriter() throws IOException { >+ //log values to ensure these values are accessible to subclasses >+ logger.log(POILogger.INFO, "_compressTmpFiles: " + _compressTmpFiles); >+ logger.log(POILogger.INFO, "_sharedStringSource: " + _sharedStringSource); >+ return new SheetDataWriterWithDecorator(); >+ } >+ } >+ >+ static class SheetDataWriterWithDecorator extends SheetDataWriter { >+ final static CipherAlgorithm cipherAlgorithm = CipherAlgorithm.aes128; >+ SecretKeySpec skeySpec; >+ byte[] ivBytes; >+ >+ public SheetDataWriterWithDecorator() throws IOException { >+ super(); >+ } >+ >+ void init() { >+ if(skeySpec == null) { >+ SecureRandom sr = new SecureRandom(); >+ ivBytes = new byte[16]; >+ byte[] keyBytes = new byte[16]; >+ sr.nextBytes(ivBytes); >+ sr.nextBytes(keyBytes); >+ skeySpec = new SecretKeySpec(keyBytes, cipherAlgorithm.jceId); >+ } >+ } >+ >+ @Override >+ protected OutputStream decorateOutputStream(FileOutputStream fos) { >+ init(); >+ Cipher ciEnc = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.ENCRYPT_MODE, "PKCS5Padding"); >+ return new CipherOutputStream(fos, ciEnc); >+ } >+ >+ @Override >+ protected InputStream decorateInputStream(FileInputStream fis) { >+ Cipher ciDec = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.DECRYPT_MODE, "PKCS5Padding"); >+ return new CipherInputStream(fis, ciDec); >+ } >+ >+ } >+} >-- >2.2.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 60153
:
34284
|
34286
|
34346