]> source.dussan.org Git - poi.git/commitdiff
- SonarCube fixes
authorAndreas Beeker <kiwiwings@apache.org>
Fri, 11 Nov 2016 23:22:43 +0000 (23:22 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Fri, 11 Nov 2016 23:22:43 +0000 (23:22 +0000)
- moved SecureTempFile classes to OOXML, because of duplicated code in test and examples packages

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1769363 13f79535-47bb-0310-9956-ffa450edef68

40 files changed:
src/examples/src/org/apache/poi/crypt/examples/AesZipFileZipEntrySource.java [deleted file]
src/examples/src/org/apache/poi/crypt/examples/EncryptedTempData.java [deleted file]
src/examples/src/org/apache/poi/crypt/examples/EncryptionUtils.java
src/examples/src/org/apache/poi/examples/util/TempFileUtils.java
src/examples/src/org/apache/poi/xssf/eventusermodel/examples/LoadPasswordProtectedXlsxStreaming.java
src/examples/src/org/apache/poi/xssf/streaming/examples/SXSSFWorkbookWithCustomZipEntrySource.java [deleted file]
src/examples/src/org/apache/poi/xssf/streaming/examples/SavePasswordProtectedXlsx.java
src/examples/src/org/apache/poi/xssf/usermodel/examples/LoadPasswordProtectedXlsx.java
src/java/org/apache/poi/hssf/OldExcelFormatException.java
src/java/org/apache/poi/hssf/record/FilePassRecord.java
src/java/org/apache/poi/poifs/crypt/ChunkedCipherInputStream.java
src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java
src/java/org/apache/poi/poifs/crypt/Decryptor.java
src/java/org/apache/poi/poifs/crypt/Encryptor.java
src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4Decryptor.java
src/java/org/apache/poi/poifs/crypt/binaryrc4/BinaryRC4Encryptor.java
src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDecryptor.java
src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentOutputStream.java
src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIEncryptor.java
src/java/org/apache/poi/poifs/crypt/xor/XORDecryptor.java
src/java/org/apache/poi/poifs/crypt/xor/XOREncryptionVerifier.java
src/java/org/apache/poi/poifs/crypt/xor/XOREncryptor.java
src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java
src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionVerifier.java
src/ooxml/java/org/apache/poi/poifs/crypt/temp/AesZipFileZipEntrySource.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/poifs/crypt/temp/EncryptedTempData.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/poifs/crypt/temp/SXSSFWorkbookWithCustomZipEntrySource.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/poifs/crypt/temp/SheetDataWriterWithDecorator.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFReader.java
src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java
src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
src/ooxml/testcases/org/apache/poi/poifs/crypt/AesZipFileZipEntrySource.java [deleted file]
src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSecureTempZip.java
src/ooxml/testcases/org/apache/poi/xssf/streaming/TempFileRecordingSXSSFWorkbookWithCustomZipEntrySource.java
src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbookWithCustomZipEntrySource.java
src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV5.java
src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java

diff --git a/src/examples/src/org/apache/poi/crypt/examples/AesZipFileZipEntrySource.java b/src/examples/src/org/apache/poi/crypt/examples/AesZipFileZipEntrySource.java
deleted file mode 100644 (file)
index af281e2..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- *  ====================================================================
- *    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.crypt.examples;
-
-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.poifs.crypt.ChainingMode;
-import org.apache.poi.poifs.crypt.CipherAlgorithm;
-import org.apache.poi.poifs.crypt.CryptoFunctions;
-import org.apache.poi.util.IOUtils;
-import org.apache.poi.util.TempFile;
-
-/**
- * An example <code>ZipEntrySource</code> that has encrypted temp files to ensure that
- * sensitive data is not stored in raw format on disk.
- */
-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!
-     */
-    @Override
-    public Enumeration<? extends ZipEntry> getEntries() {
-        return zipFile.entries();
-    }
-    
-    @Override
-    public InputStream getInputStream(ZipEntry entry) throws IOException {
-        InputStream is = zipFile.getInputStream(entry);
-        return new CipherInputStream(is, ci);
-    }
-    
-    @Override
-    public void close() throws IOException {
-        if(!closed) {
-            zipFile.close();
-            tmpFile.delete();
-        }
-        closed = true;
-    }
-
-    @Override
-    public boolean isClosed() {
-        return closed;
-    }
-
-    public static AesZipFileZipEntrySource 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
-                @Override
-                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 AesZipFileZipEntrySource 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);
-    }
-    
-}
\ No newline at end of file
diff --git a/src/examples/src/org/apache/poi/crypt/examples/EncryptedTempData.java b/src/examples/src/org/apache/poi/crypt/examples/EncryptedTempData.java
deleted file mode 100644 (file)
index e4c5796..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *  ====================================================================
- *    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.crypt.examples;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-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.poifs.crypt.ChainingMode;
-import org.apache.poi.poifs.crypt.CipherAlgorithm;
-import org.apache.poi.poifs.crypt.CryptoFunctions;
-import org.apache.poi.util.TempFile;
-
-/**
- * EncryptedTempData can be used to buffer binary data in a secure way, by using encrypted temp files.
- */
-public class EncryptedTempData {
-    final static CipherAlgorithm cipherAlgorithm = CipherAlgorithm.aes128;
-    final SecretKeySpec skeySpec;
-    final byte[] ivBytes;
-    final File tempFile;
-    
-    public EncryptedTempData() throws IOException {
-        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);
-        tempFile = TempFile.createTempFile("poi-temp-data", ".tmp");
-    }
-
-    public OutputStream getOutputStream() throws IOException {
-        Cipher ciEnc = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.ENCRYPT_MODE, null);
-        return new CipherOutputStream(new FileOutputStream(tempFile), ciEnc);
-    }
-
-    public InputStream getInputStream() throws IOException {
-        Cipher ciDec = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.DECRYPT_MODE, null);
-        return new CipherInputStream(new FileInputStream(tempFile), ciDec);
-    }
-    
-    public void dispose() {
-        tempFile.delete();
-    }
-}
index acbfdd1890ec26f45fba8b10168ee92f29fc9401..c2b795cb5ebc11444a2e7bd9ecf2df65f10d56f3 100644 (file)
@@ -27,6 +27,9 @@ import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.IOUtils;
 
 public class EncryptionUtils {
+    private EncryptionUtils() {
+    }
+    
     public static InputStream decrypt(final InputStream inputStream, final String pwd) throws Exception {
         try {
             POIFSFileSystem fs = new POIFSFileSystem(inputStream);
index f34f35d3cb4ed9ab93816099735dde934287684a..5d4f7ab5318b68a0b027bf147ca1fd563f91d993 100644 (file)
@@ -25,14 +25,17 @@ import java.io.IOException;
 import org.apache.poi.util.TempFile;
 
 public class TempFileUtils {
+    private TempFileUtils() {
+    }
+    
     public static void checkTempFiles() throws IOException {
         String tmpDir = System.getProperty(TempFile.JAVA_IO_TMPDIR) + "/poifiles";
         File tempDir = new File(tmpDir);
         if(tempDir.exists()) {
             String[] tempFiles = tempDir.list();
-            if(tempFiles.length > 0) {
+            if(tempFiles != null && tempFiles.length > 0) {
                 System.out.println("found files in poi temp dir " + tempDir.getAbsolutePath());
-                for(String filename : tempDir.list()) {
+                for(String filename : tempFiles) {
                     System.out.println("file: " + filename);
                 }
             }
index aa7d0ceee70e8a2221b18f25ba9917b9eff63a84..80e4c7320a935fb96375a0f9caa601e5618304ff 100644 (file)
 package org.apache.poi.xssf.eventusermodel.examples;
 
 import java.io.FileInputStream;
+import java.io.IOException;
 import java.io.InputStream;
 
-import org.apache.poi.crypt.examples.AesZipFileZipEntrySource;
 import org.apache.poi.crypt.examples.EncryptionUtils;
 import org.apache.poi.examples.util.TempFileUtils;
 import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.poifs.crypt.temp.AesZipFileZipEntrySource;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.xssf.eventusermodel.XSSFReader;
 import org.apache.poi.xssf.eventusermodel.XSSFReader.SheetIterator;
@@ -40,29 +41,25 @@ import org.apache.poi.xssf.eventusermodel.XSSFReader.SheetIterator;
  */
 public class LoadPasswordProtectedXlsxStreaming {
 
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
+        if(args.length != 2) {
+            throw new IllegalArgumentException("Expected 2 params: filename and password");
+        }
+        TempFileUtils.checkTempFiles();
+        String filename = args[0];
+        String password = args[1];
+        FileInputStream fis = new FileInputStream(filename);
         try {
-            if(args.length != 2) {
-                throw new Exception("Expected 2 params: filename and password");
-            }
-            TempFileUtils.checkTempFiles();
-            String filename = args[0];
-            String password = args[1];
-            FileInputStream fis = new FileInputStream(filename);
+            InputStream unencryptedStream = EncryptionUtils.decrypt(fis, password);
             try {
-                InputStream unencryptedStream = EncryptionUtils.decrypt(fis, password);
-                try {
-                    printSheetCount(unencryptedStream);
-                } finally {
-                    IOUtils.closeQuietly(unencryptedStream);
-                }
+                printSheetCount(unencryptedStream);
             } finally {
-                IOUtils.closeQuietly(fis);
+                IOUtils.closeQuietly(unencryptedStream);
             }
-            TempFileUtils.checkTempFiles();
-        } catch(Throwable t) {
-            t.printStackTrace();
+        } finally {
+            IOUtils.closeQuietly(fis);
         }
+        TempFileUtils.checkTempFiles();
     }
 
     public static void printSheetCount(final InputStream inputStream) throws Exception {
diff --git a/src/examples/src/org/apache/poi/xssf/streaming/examples/SXSSFWorkbookWithCustomZipEntrySource.java b/src/examples/src/org/apache/poi/xssf/streaming/examples/SXSSFWorkbookWithCustomZipEntrySource.java
deleted file mode 100644 (file)
index 48f3f3a..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *  ====================================================================
- *    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.examples;
-
-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.crypt.examples.AesZipFileZipEntrySource;
-import org.apache.poi.crypt.examples.EncryptedTempData;
-import org.apache.poi.openxml4j.util.ZipEntrySource;
-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.IOUtils;
-import org.apache.poi.xssf.streaming.SXSSFWorkbook;
-import org.apache.poi.xssf.streaming.SheetDataWriter;
-
-public class SXSSFWorkbookWithCustomZipEntrySource extends SXSSFWorkbook {
-    
-    public SXSSFWorkbookWithCustomZipEntrySource() {
-        super(20);
-        setCompressTempFiles(true);
-    }
-    
-    @Override
-    public void write(OutputStream stream) throws IOException {
-        flushSheets();
-        EncryptedTempData tempData = new EncryptedTempData();
-        ZipEntrySource source = null;
-        try {
-            OutputStream os = tempData.getOutputStream();
-            try {
-                getXSSFWorkbook().write(os);
-            } finally {
-                IOUtils.closeQuietly(os);
-            }
-            // provide ZipEntrySource to poi which decrypts on the fly
-            source = AesZipFileZipEntrySource.createZipEntrySource(tempData.getInputStream());
-            injectData(source, stream);
-        } catch (GeneralSecurityException e) {
-            throw new IOException(e);
-        } finally {
-            tempData.dispose();
-            IOUtils.closeQuietly(source);
-        }
-    }
-    
-    @Override
-    protected SheetDataWriter createSheetDataWriter() throws IOException {
-        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);
-        }
-    }
-}
index 4c741873a590160586a5355ae368c7941516c29f..9aaa8bf276297c6f649f901f847534e344f457fd 100644 (file)
@@ -24,13 +24,14 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.security.GeneralSecurityException;
 
-import org.apache.poi.crypt.examples.EncryptedTempData;
 import org.apache.poi.examples.util.TempFileUtils;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.poifs.crypt.EncryptionInfo;
 import org.apache.poi.poifs.crypt.EncryptionMode;
 import org.apache.poi.poifs.crypt.Encryptor;
+import org.apache.poi.poifs.crypt.temp.EncryptedTempData;
+import org.apache.poi.poifs.crypt.temp.SXSSFWorkbookWithCustomZipEntrySource;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.xssf.streaming.SXSSFCell;
@@ -47,42 +48,38 @@ import org.apache.poi.xssf.streaming.SXSSFSheet;
  */
 public class SavePasswordProtectedXlsx {
 
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
+        if(args.length != 2) {
+            throw new IllegalArgumentException("Expected 2 params: filename and password");
+        }
+        TempFileUtils.checkTempFiles();
+        String filename = args[0];
+        String password = args[1];
+        SXSSFWorkbookWithCustomZipEntrySource wb = new SXSSFWorkbookWithCustomZipEntrySource();
         try {
-            if(args.length != 2) {
-                throw new Exception("Expected 2 params: filename and password");
-            }
-            TempFileUtils.checkTempFiles();
-            String filename = args[0];
-            String password = args[1];
-            SXSSFWorkbookWithCustomZipEntrySource wb = new SXSSFWorkbookWithCustomZipEntrySource();
-            try {
-                for(int i = 0; i < 10; i++) {
-                    SXSSFSheet sheet = wb.createSheet("Sheet" + i);
-                    for(int r = 0; r < 1000; r++) {
-                        SXSSFRow row = sheet.createRow(r);
-                        for(int c = 0; c < 100; c++) {
-                            SXSSFCell cell = row.createCell(c);
-                            cell.setCellValue("abcd");
-                        }
+            for(int i = 0; i < 10; i++) {
+                SXSSFSheet sheet = wb.createSheet("Sheet" + i);
+                for(int r = 0; r < 1000; r++) {
+                    SXSSFRow row = sheet.createRow(r);
+                    for(int c = 0; c < 100; c++) {
+                        SXSSFCell cell = row.createCell(c);
+                        cell.setCellValue("abcd");
                     }
                 }
-                EncryptedTempData tempData = new EncryptedTempData();
-                try {
-                    wb.write(tempData.getOutputStream());
-                    save(tempData.getInputStream(), filename, password);
-                    System.out.println("Saved " + filename);
-                } finally {
-                    tempData.dispose();
-                }
+            }
+            EncryptedTempData tempData = new EncryptedTempData();
+            try {
+                wb.write(tempData.getOutputStream());
+                save(tempData.getInputStream(), filename, password);
+                System.out.println("Saved " + filename);
             } finally {
-                wb.close();
-                wb.dispose();
+                tempData.dispose();
             }
-            TempFileUtils.checkTempFiles();
-        } catch(Throwable t) {
-            t.printStackTrace();
+        } finally {
+            wb.close();
+            wb.dispose();
         }
+        TempFileUtils.checkTempFiles();
     }
     
     public static void save(final InputStream inputStream, final String filename, final String pwd)
index 7bb677bf22de031b4d3341ae6bb17e6cb1d49772..da6032f867914ea172c0e0a2d969af3878290116 100644 (file)
@@ -22,10 +22,10 @@ package org.apache.poi.xssf.usermodel.examples;
 import java.io.FileInputStream;
 import java.io.InputStream;
 
-import org.apache.poi.crypt.examples.AesZipFileZipEntrySource;
 import org.apache.poi.crypt.examples.EncryptionUtils;
 import org.apache.poi.examples.util.TempFileUtils;
 import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.poifs.crypt.temp.AesZipFileZipEntrySource;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
@@ -38,29 +38,25 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  */
 public class LoadPasswordProtectedXlsx {
     
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
+        if(args.length != 2) {
+            throw new IllegalArgumentException("Expected 2 params: filename and password");
+        }
+        TempFileUtils.checkTempFiles();
+        String filename = args[0];
+        String password = args[1];
+        FileInputStream fis = new FileInputStream(filename);
         try {
-            if(args.length != 2) {
-                throw new Exception("Expected 2 params: filename and password");
-            }
-            TempFileUtils.checkTempFiles();
-            String filename = args[0];
-            String password = args[1];
-            FileInputStream fis = new FileInputStream(filename);
+            InputStream unencryptedStream = EncryptionUtils.decrypt(fis, password);
             try {
-                InputStream unencryptedStream = EncryptionUtils.decrypt(fis, password);
-                try {
-                    printSheetCount(unencryptedStream);
-                } finally {
-                    IOUtils.closeQuietly(unencryptedStream);
-                }
+                printSheetCount(unencryptedStream);
             } finally {
-                IOUtils.closeQuietly(fis);
+                IOUtils.closeQuietly(unencryptedStream);
             }
-            TempFileUtils.checkTempFiles();
-        } catch(Throwable t) {
-            t.printStackTrace();
+        } finally {
+            IOUtils.closeQuietly(fis);
         }
+        TempFileUtils.checkTempFiles();
     }
     
     public static void printSheetCount(final InputStream inputStream) throws Exception {
index e42e613d84eff31fb0872c2bf02eeeea3d87ca16..beb8c02c7329096d90e9e2417ea5b8bfb9a8f89e 100644 (file)
 package org.apache.poi.hssf;
 
 import org.apache.poi.OldFileFormatException;
+import org.apache.poi.util.Removal;
 
+/**
+ * @deprecated POI 3.16 beta 1. Use {@link org.apache.poi.OldFileFormatException}
+ */
+@Removal(version="3.18")
 public class OldExcelFormatException extends OldFileFormatException {
        public OldExcelFormatException(String s) {
                super(s);
index 99f37e535f6410221f7cd6dd7d9472afce7eeb05..ab941fad5f79ab04d173090f5e24a199ce8cbcea 100644 (file)
@@ -110,7 +110,7 @@ public final class FilePassRecord extends StandardRecord implements Cloneable {
                 ((CryptoAPIEncryptionVerifier)encryptionInfo.getVerifier()).write(bos);
                 break;
             default:
-                throw new RuntimeException("not supported");
+                throw new EncryptedDocumentException("not supported");
         }
 
         out.write(data, 0, bos.getWriteIndex());
@@ -140,16 +140,16 @@ public final class FilePassRecord extends StandardRecord implements Cloneable {
 
        @Override
     public String toString() {
-               StringBuffer buffer = new StringBuffer();
+           StringBuilder buffer = new StringBuilder();
 
                buffer.append("[FILEPASS]\n");
-               buffer.append("    .type = ").append(HexDump.shortToHex(encryptionType)).append("\n");
+               buffer.append("    .type = ").append(HexDump.shortToHex(encryptionType)).append('\n');
         String prefix = "     ."+encryptionInfo.getEncryptionMode();
-        buffer.append(prefix+".info = ").append(HexDump.shortToHex(encryptionInfo.getVersionMajor())).append("\n");
-        buffer.append(prefix+".ver  = ").append(HexDump.shortToHex(encryptionInfo.getVersionMinor())).append("\n");
-        buffer.append(prefix+".salt = ").append(HexDump.toHex(encryptionInfo.getVerifier().getSalt())).append("\n");
-        buffer.append(prefix+".verifier = ").append(HexDump.toHex(encryptionInfo.getVerifier().getEncryptedVerifier())).append("\n");
-        buffer.append(prefix+".verifierHash = ").append(HexDump.toHex(encryptionInfo.getVerifier().getEncryptedVerifierHash())).append("\n");
+        buffer.append(prefix+".info = ").append(HexDump.shortToHex(encryptionInfo.getVersionMajor())).append('\n');
+        buffer.append(prefix+".ver  = ").append(HexDump.shortToHex(encryptionInfo.getVersionMinor())).append('\n');
+        buffer.append(prefix+".salt = ").append(HexDump.toHex(encryptionInfo.getVerifier().getSalt())).append('\n');
+        buffer.append(prefix+".verifier = ").append(HexDump.toHex(encryptionInfo.getVerifier().getEncryptedVerifier())).append('\n');
+        buffer.append(prefix+".verifierHash = ").append(HexDump.toHex(encryptionInfo.getVerifier().getEncryptedVerifierHash())).append('\n');
                buffer.append("[/FILEPASS]\n");
                return buffer.toString();
        }
index 1045b3058bcba4ab52b226308b34e730e69e0781..db3d724e4c06c2351cc734991eef9aa826f1c568 100644 (file)
@@ -32,16 +32,16 @@ import org.apache.poi.util.LittleEndianInputStream;
 \r
 @Internal\r
 public abstract class ChunkedCipherInputStream extends LittleEndianInputStream {\r
-    private final int _chunkSize;\r
-    private final int _chunkBits;\r
+    private final int chunkSize;\r
+    private final int chunkBits;\r
 \r
-    private final long _size;\r
-    private final byte[] _chunk, _plain;\r
-    private final Cipher _cipher;\r
+    private final long size;\r
+    private final byte[] chunk, plain;\r
+    private final Cipher cipher;\r
 \r
-    private int _lastIndex;\r
-    private long _pos;\r
-    private boolean _chunkIsValid = false;\r
+    private int lastIndex;\r
+    private long pos;\r
+    private boolean chunkIsValid = false;\r
 \r
     public ChunkedCipherInputStream(InputStream stream, long size, int chunkSize)\r
     throws GeneralSecurityException {\r
@@ -51,24 +51,24 @@ public abstract class ChunkedCipherInputStream extends LittleEndianInputStream {
     public ChunkedCipherInputStream(InputStream stream, long size, int chunkSize, int initialPos)\r
     throws GeneralSecurityException {\r
         super(stream);\r
-        _size = size;\r
-        _pos = initialPos;\r
-        this._chunkSize = chunkSize;\r
+        this.size = size;\r
+        this.pos = initialPos;\r
+        this.chunkSize = chunkSize;\r
         int cs = chunkSize == -1 ? 4096 : chunkSize;\r
-        _chunk = new byte[cs];\r
-        _plain = new byte[cs];\r
-        _chunkBits = Integer.bitCount(_chunk.length-1);\r
-        _lastIndex = (int)(_pos >> _chunkBits);\r
-        _cipher = initCipherForBlock(null, _lastIndex);\r
+        this.chunk = new byte[cs];\r
+        this.plain = new byte[cs];\r
+        this.chunkBits = Integer.bitCount(chunk.length-1);\r
+        this.lastIndex = (int)(pos >> chunkBits);\r
+        this.cipher = initCipherForBlock(null, lastIndex);\r
     }\r
 \r
     public final Cipher initCipherForBlock(int block) throws IOException, GeneralSecurityException {\r
-        if (_chunkSize != -1) {\r
+        if (chunkSize != -1) {\r
             throw new GeneralSecurityException("the cipher block can only be set for streaming encryption, e.g. CryptoAPI...");\r
         }\r
 \r
-        _chunkIsValid = false;\r
-        return initCipherForBlock(_cipher, block);\r
+        chunkIsValid = false;\r
+        return initCipherForBlock(cipher, block);\r
     }\r
 \r
     protected abstract Cipher initCipherForBlock(Cipher existing, int block)\r
@@ -100,28 +100,28 @@ public abstract class ChunkedCipherInputStream extends LittleEndianInputStream {
 \r
         final int chunkMask = getChunkMask();\r
         while (len > 0) {\r
-            if (!_chunkIsValid) {\r
+            if (!chunkIsValid) {\r
                 try {\r
                     nextChunk();\r
-                    _chunkIsValid = true;\r
+                    chunkIsValid = true;\r
                 } catch (GeneralSecurityException e) {\r
                     throw new EncryptedDocumentException(e.getMessage(), e);\r
                 }\r
             }\r
-            int count = (int)(_chunk.length - (_pos & chunkMask));\r
+            int count = (int)(chunk.length - (pos & chunkMask));\r
             int avail = available();\r
             if (avail == 0) {\r
                 return total;\r
             }\r
             count = Math.min(avail, Math.min(count, len));\r
 \r
-            System.arraycopy(readPlain ? _plain : _chunk, (int)(_pos & chunkMask), b, off, count);\r
+            System.arraycopy(readPlain ? plain : chunk, (int)(pos & chunkMask), b, off, count);\r
 \r
             off += count;\r
             len -= count;\r
-            _pos += count;\r
-            if ((_pos & chunkMask) == 0) {\r
-                _chunkIsValid = false;\r
+            pos += count;\r
+            if ((pos & chunkMask) == 0) {\r
+                chunkIsValid = false;\r
             }\r
             total += count;\r
         }\r
@@ -131,13 +131,13 @@ public abstract class ChunkedCipherInputStream extends LittleEndianInputStream {
 \r
     @Override\r
     public long skip(final long n) throws IOException {\r
-        long start = _pos;\r
+        long start = pos;\r
         long skip = Math.min(remainingBytes(), n);\r
 \r
-        if ((((_pos + skip) ^ start) & ~getChunkMask()) != 0) {\r
-            _chunkIsValid = false;\r
+        if ((((pos + skip) ^ start) & ~getChunkMask()) != 0) {\r
+            chunkIsValid = false;\r
         }\r
-        _pos += skip;\r
+        pos += skip;\r
         return skip;\r
     }\r
 \r
@@ -152,7 +152,7 @@ public abstract class ChunkedCipherInputStream extends LittleEndianInputStream {
      * @return the remaining byte until EOF\r
      */\r
     private int remainingBytes() {\r
-        return (int)(_size - _pos);\r
+        return (int)(size - pos);\r
     }\r
 \r
     @Override\r
@@ -171,35 +171,35 @@ public abstract class ChunkedCipherInputStream extends LittleEndianInputStream {
     }\r
 \r
     protected int getChunkMask() {\r
-        return _chunk.length-1;\r
+        return chunk.length-1;\r
     }\r
 \r
     private void nextChunk() throws GeneralSecurityException, IOException {\r
-        if (_chunkSize != -1) {\r
-            int index = (int)(_pos >> _chunkBits);\r
-            initCipherForBlock(_cipher, index);\r
+        if (chunkSize != -1) {\r
+            int index = (int)(pos >> chunkBits);\r
+            initCipherForBlock(cipher, index);\r
 \r
-            if (_lastIndex != index) {\r
-                super.skip((index - _lastIndex) << _chunkBits);\r
+            if (lastIndex != index) {\r
+                super.skip((index - lastIndex) << chunkBits);\r
             }\r
 \r
-            _lastIndex = index + 1;\r
+            lastIndex = index + 1;\r
         }\r
 \r
-        final int todo = (int)Math.min(_size, _chunk.length);\r
+        final int todo = (int)Math.min(size, chunk.length);\r
         int readBytes = 0, totalBytes = 0;\r
         do {\r
-            readBytes = super.read(_plain, totalBytes, todo-totalBytes);\r
+            readBytes = super.read(plain, totalBytes, todo-totalBytes);\r
             totalBytes += Math.max(0, readBytes);\r
         } while (readBytes != -1 && totalBytes < todo);\r
 \r
-        if (readBytes == -1 && _pos+totalBytes < _size && _size < Integer.MAX_VALUE) {\r
+        if (readBytes == -1 && pos+totalBytes < size && size < Integer.MAX_VALUE) {\r
             throw new EOFException("buffer underrun");\r
         }\r
 \r
-        System.arraycopy(_plain, 0, _chunk, 0, totalBytes);\r
+        System.arraycopy(plain, 0, chunk, 0, totalBytes);\r
 \r
-        invokeCipher(totalBytes, totalBytes == _chunkSize);\r
+        invokeCipher(totalBytes, totalBytes == chunkSize);\r
     }\r
 \r
     /**\r
@@ -212,9 +212,9 @@ public abstract class ChunkedCipherInputStream extends LittleEndianInputStream {
      */\r
     protected int invokeCipher(int totalBytes, boolean doFinal) throws GeneralSecurityException {\r
         if (doFinal) {\r
-            return _cipher.doFinal(_chunk, 0, totalBytes, _chunk);\r
+            return cipher.doFinal(chunk, 0, totalBytes, chunk);\r
         } else {\r
-            return _cipher.update(_chunk, 0, totalBytes, _chunk);\r
+            return cipher.update(chunk, 0, totalBytes, chunk);\r
         }\r
     }\r
 \r
@@ -258,20 +258,20 @@ public abstract class ChunkedCipherInputStream extends LittleEndianInputStream {
      * @return the chunk bytes\r
      */\r
     protected byte[] getChunk() {\r
-        return _chunk;\r
+        return chunk;\r
     }\r
 \r
     /**\r
      * @return the plain bytes\r
      */\r
     protected byte[] getPlain() {\r
-        return _plain;\r
+        return plain;\r
     }\r
 \r
     /**\r
      * @return the absolute position in the stream\r
      */\r
     public long getPos() {\r
-        return _pos;\r
+        return pos;\r
     }\r
 }\r
index 836aae2bbc3a4572eac41f628728e4d86fd435e5..a8e920dc1179d20718320c8ed236b4f9174f4bb9 100644 (file)
@@ -49,47 +49,50 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream {
     private static final POILogger LOG = POILogFactory.getLogger(ChunkedCipherOutputStream.class);\r
     private static final int STREAMING = -1;\r
 \r
-    private final int _chunkSize;\r
-    private final int _chunkBits;\r
+    private final int chunkSize;\r
+    private final int chunkBits;\r
 \r
-    private final byte[] _chunk;\r
-    private final BitSet _plainByteFlags;\r
-    private final File _fileOut;\r
-    private final DirectoryNode _dir;\r
+    private final byte[] chunk;\r
+    private final BitSet plainByteFlags;\r
+    private final File fileOut;\r
+    private final DirectoryNode dir;\r
 \r
-    private long _pos = 0;\r
-    private long _totalPos = 0;\r
-    private long _written = 0;\r
-    private Cipher _cipher;\r
+    private long pos = 0;\r
+    private long totalPos = 0;\r
+    private long written = 0;\r
+    \r
+    // the cipher can't be final, because for the last chunk we change the padding\r
+    // and therefore need to change the cipher too\r
+    private Cipher cipher;\r
 \r
     public ChunkedCipherOutputStream(DirectoryNode dir, int chunkSize) throws IOException, GeneralSecurityException {\r
         super(null);\r
-        this._chunkSize = chunkSize;\r
+        this.chunkSize = chunkSize;\r
         int cs = chunkSize == STREAMING ? 4096 : chunkSize;\r
-        _chunk = new byte[cs];\r
-        _plainByteFlags = new BitSet(cs);\r
-        _chunkBits = Integer.bitCount(cs-1);\r
-        _fileOut = TempFile.createTempFile("encrypted_package", "crypt");\r
-        _fileOut.deleteOnExit();\r
-        this.out = new FileOutputStream(_fileOut);\r
-        this._dir = dir;\r
-        _cipher = initCipherForBlock(null, 0, false);\r
+        this.chunk = new byte[cs];\r
+        this.plainByteFlags = new BitSet(cs);\r
+        this.chunkBits = Integer.bitCount(cs-1);\r
+        this.fileOut = TempFile.createTempFile("encrypted_package", "crypt");\r
+        this.fileOut.deleteOnExit();\r
+        this.out = new FileOutputStream(fileOut);\r
+        this.dir = dir;\r
+        this.cipher = initCipherForBlock(null, 0, false);\r
     }\r
 \r
     public ChunkedCipherOutputStream(OutputStream stream, int chunkSize) throws IOException, GeneralSecurityException {\r
         super(stream);\r
-        this._chunkSize = chunkSize;\r
+        this.chunkSize = chunkSize;\r
         int cs = chunkSize == STREAMING ? 4096 : chunkSize;\r
-        _chunk = new byte[cs];\r
-        _plainByteFlags = new BitSet(cs);\r
-        _chunkBits = Integer.bitCount(cs-1);\r
-        _fileOut = null;\r
-        _dir = null;\r
-        _cipher = initCipherForBlock(null, 0, false);\r
+        this.chunk = new byte[cs];\r
+        this.plainByteFlags = new BitSet(cs);\r
+        this.chunkBits = Integer.bitCount(cs-1);\r
+        this.fileOut = null;\r
+        this.dir = null;\r
+        this.cipher = initCipherForBlock(null, 0, false);\r
     }\r
 \r
     public final Cipher initCipherForBlock(int block, boolean lastChunk) throws IOException, GeneralSecurityException {\r
-        return initCipherForBlock(_cipher, block, lastChunk);\r
+        return initCipherForBlock(cipher, block, lastChunk);\r
     }\r
 \r
     protected abstract Cipher initCipherForBlock(Cipher existing, int block, boolean lastChunk)\r
@@ -131,40 +134,40 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream {
 \r
         final int chunkMask = getChunkMask();\r
         while (len > 0) {\r
-            int posInChunk = (int)(_pos & chunkMask);\r
-            int nextLen = Math.min(_chunk.length-posInChunk, len);\r
-            System.arraycopy(b, off, _chunk, posInChunk, nextLen);\r
+            int posInChunk = (int)(pos & chunkMask);\r
+            int nextLen = Math.min(chunk.length-posInChunk, len);\r
+            System.arraycopy(b, off, chunk, posInChunk, nextLen);\r
             if (writePlain) {\r
-                _plainByteFlags.set(posInChunk, posInChunk+nextLen);\r
+                plainByteFlags.set(posInChunk, posInChunk+nextLen);\r
             }\r
-            _pos += nextLen;\r
-            _totalPos += nextLen;\r
+            pos += nextLen;\r
+            totalPos += nextLen;\r
             off += nextLen;\r
             len -= nextLen;\r
-            if ((_pos & chunkMask) == 0) {\r
+            if ((pos & chunkMask) == 0) {\r
                 writeChunk(len > 0);\r
             }\r
         }\r
     }\r
 \r
     protected int getChunkMask() {\r
-        return _chunk.length-1;\r
+        return chunk.length-1;\r
     }\r
 \r
     protected void writeChunk(boolean continued) throws IOException {\r
-        if (_pos == 0 || _totalPos == _written) {\r
+        if (pos == 0 || totalPos == written) {\r
             return;\r
         }\r
 \r
-        int posInChunk = (int)(_pos & getChunkMask());\r
+        int posInChunk = (int)(pos & getChunkMask());\r
 \r
         // normally posInChunk is 0, i.e. on the next chunk (-> index-1)\r
         // but if called on close(), posInChunk is somewhere within the chunk data\r
-        int index = (int)(_pos >> _chunkBits);\r
+        int index = (int)(pos >> chunkBits);\r
         boolean lastChunk;\r
         if (posInChunk==0) {\r
             index--;\r
-            posInChunk = _chunk.length;\r
+            posInChunk = chunk.length;\r
             lastChunk = false;\r
         } else {\r
             // pad the last chunk\r
@@ -174,27 +177,27 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream {
         int ciLen;\r
         try {\r
             boolean doFinal = true;\r
-            long oldPos = _pos;\r
+            long oldPos = pos;\r
             // reset stream (not only) in case we were interrupted by plain stream parts\r
             // this also needs to be set to prevent an endless loop\r
-            _pos = 0;\r
-            if (_chunkSize == STREAMING) {\r
+            pos = 0;\r
+            if (chunkSize == STREAMING) {\r
                 if (continued) {\r
                     doFinal = false;\r
                 }\r
             } else {\r
-                _cipher = initCipherForBlock(_cipher, index, lastChunk);\r
+                cipher = initCipherForBlock(cipher, index, lastChunk);\r
                 // restore pos - only streaming chunks will be reset\r
-                _pos = oldPos;\r
+                pos = oldPos;\r
             }\r
             ciLen = invokeCipher(posInChunk, doFinal);\r
         } catch (GeneralSecurityException e) {\r
             throw new IOException("can't re-/initialize cipher", e);\r
         }\r
 \r
-        out.write(_chunk, 0, ciLen);\r
-        _plainByteFlags.clear();\r
-        _written += ciLen;\r
+        out.write(chunk, 0, ciLen);\r
+        plainByteFlags.clear();\r
+        written += ciLen;\r
     }\r
 \r
     /**\r
@@ -206,14 +209,14 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream {
      * @throws ShortBufferException \r
      */\r
     protected int invokeCipher(int posInChunk, boolean doFinal) throws GeneralSecurityException {\r
-        byte plain[] = (_plainByteFlags.isEmpty()) ? null : _chunk.clone();\r
+        byte plain[] = (plainByteFlags.isEmpty()) ? null : chunk.clone();\r
 \r
         int ciLen = (doFinal)\r
-            ? _cipher.doFinal(_chunk, 0, posInChunk, _chunk)\r
-            : _cipher.update(_chunk, 0, posInChunk, _chunk);\r
+            ? cipher.doFinal(chunk, 0, posInChunk, chunk)\r
+            : cipher.update(chunk, 0, posInChunk, chunk);\r
         \r
-        for (int i = _plainByteFlags.nextSetBit(0); i >= 0 && i < posInChunk; i = _plainByteFlags.nextSetBit(i+1)) {\r
-            _chunk[i] = plain[i];\r
+        for (int i = plainByteFlags.nextSetBit(0); i >= 0 && i < posInChunk; i = plainByteFlags.nextSetBit(i+1)) {\r
+            chunk[i] = plain[i];\r
         }\r
         \r
         return ciLen;\r
@@ -226,11 +229,11 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream {
 \r
             super.close();\r
 \r
-            if (_fileOut != null) {\r
-                int oleStreamSize = (int)(_fileOut.length()+LittleEndianConsts.LONG_SIZE);\r
-                calculateChecksum(_fileOut, (int)_pos);\r
-                _dir.createDocument(DEFAULT_POIFS_ENTRY, oleStreamSize, new EncryptedPackageWriter());\r
-                createEncryptionInfoEntry(_dir, _fileOut);\r
+            if (fileOut != null) {\r
+                int oleStreamSize = (int)(fileOut.length()+LittleEndianConsts.LONG_SIZE);\r
+                calculateChecksum(fileOut, (int)pos);\r
+                dir.createDocument(DEFAULT_POIFS_ENTRY, oleStreamSize, new EncryptedPackageWriter());\r
+                createEncryptionInfoEntry(dir, fileOut);\r
             }\r
         } catch (GeneralSecurityException e) {\r
             throw new IOException(e);\r
@@ -238,19 +241,19 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream {
     }\r
     \r
     protected byte[] getChunk() {\r
-        return _chunk;\r
+        return chunk;\r
     }\r
 \r
     protected BitSet getPlainByteFlags() {\r
-        return _plainByteFlags;\r
+        return plainByteFlags;\r
     }\r
 \r
     protected long getPos() {\r
-        return _pos;\r
+        return pos;\r
     }\r
 \r
     protected long getTotalPos() {\r
-        return _totalPos;\r
+        return totalPos;\r
     }\r
 \r
     /**\r
@@ -274,17 +277,17 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream {
                 // Note that the actual size of the \EncryptedPackage stream (1) can be larger than this\r
                 // value, depending on the block size of the chosen encryption algorithm\r
                 byte buf[] = new byte[LittleEndianConsts.LONG_SIZE];\r
-                LittleEndian.putLong(buf, 0, _pos);\r
+                LittleEndian.putLong(buf, 0, pos);\r
                 os.write(buf);\r
 \r
-                FileInputStream fis = new FileInputStream(_fileOut);\r
+                FileInputStream fis = new FileInputStream(fileOut);\r
                 IOUtils.copy(fis, os);\r
                 fis.close();\r
 \r
                 os.close();\r
 \r
-                if (!_fileOut.delete()) {\r
-                    LOG.log(POILogger.ERROR, "Can't delete temporary encryption file: "+_fileOut);\r
+                if (!fileOut.delete()) {\r
+                    LOG.log(POILogger.ERROR, "Can't delete temporary encryption file: "+fileOut);\r
                 }\r
             } catch (IOException e) {\r
                 throw new EncryptedDocumentException(e);\r
index 2030029551e06ef9a5f1ebdf30bf58b0107e2f8c..da746d896efdf4e7d5aa6beb3a84a93a11f9e5dd 100644 (file)
@@ -67,7 +67,7 @@ public abstract class Decryptor implements Cloneable {
      */
     public InputStream getDataStream(InputStream stream, int size, int initialPos)
         throws IOException, GeneralSecurityException {
-        throw new RuntimeException("this decryptor doesn't support reading from a stream");
+        throw new EncryptedDocumentException("this decryptor doesn't support reading from a stream");
     }
 
     /**
@@ -78,7 +78,7 @@ public abstract class Decryptor implements Cloneable {
      * @param chunkSize the chunk size, i.e. the block size with the same encryption key
      */
     public void setChunkSize(int chunkSize) {
-        throw new RuntimeException("this decryptor doesn't support changing the chunk size");
+        throw new EncryptedDocumentException("this decryptor doesn't support changing the chunk size");
     }
 
     /**
@@ -91,7 +91,7 @@ public abstract class Decryptor implements Cloneable {
      */
     public Cipher initCipherForBlock(Cipher cipher, int block)
     throws GeneralSecurityException {
-        throw new RuntimeException("this decryptor doesn't support initCipherForBlock");
+        throw new EncryptedDocumentException("this decryptor doesn't support initCipherForBlock");
     }
     
     public abstract boolean verifyPassword(String password)
index 546c9662850933ff866647d841280ea1028735c9..f4c0c1639f8417c398067139f339cbf156f12019 100644 (file)
@@ -23,6 +23,7 @@ import java.security.GeneralSecurityException;
 import javax.crypto.SecretKey;\r
 import javax.crypto.spec.SecretKeySpec;\r
 \r
+import org.apache.poi.EncryptedDocumentException;\r
 import org.apache.poi.poifs.filesystem.DirectoryNode;\r
 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;\r
 import org.apache.poi.poifs.filesystem.OPOIFSFileSystem;\r
@@ -63,7 +64,7 @@ public abstract class Encryptor implements Cloneable {
 \r
     public ChunkedCipherOutputStream getDataStream(OutputStream stream, int initialOffset)\r
     throws IOException, GeneralSecurityException {\r
-        throw new RuntimeException("this decryptor doesn't support writing directly to a stream");\r
+        throw new EncryptedDocumentException("this decryptor doesn't support writing directly to a stream");\r
     }\r
     \r
     public SecretKey getSecretKey() {\r
@@ -90,7 +91,7 @@ public abstract class Encryptor implements Cloneable {
      * @param chunkSize the chunk size, i.e. the block size with the same encryption key\r
      */\r
     public void setChunkSize(int chunkSize) {\r
-        throw new RuntimeException("this decryptor doesn't support changing the chunk size");\r
+        throw new EncryptedDocumentException("this decryptor doesn't support changing the chunk size");\r
     }\r
     \r
     @Override\r
index b6d8eda008a89ae480833bdaeddc728da83b013e..e02273407cf11e3b0c9a1b7f1b23d9f4e54adf74 100644 (file)
@@ -35,8 +35,8 @@ import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.StringUtil;\r
 \r
 public class BinaryRC4Decryptor extends Decryptor implements Cloneable {\r
-    private long _length = -1L;\r
-    private int _chunkSize = 512;\r
+    private long length = -1L;\r
+    private int chunkSize = 512;\r
     \r
     private class BinaryRC4CipherInputStream extends ChunkedCipherInputStream {\r
 \r
@@ -48,12 +48,12 @@ public class BinaryRC4Decryptor extends Decryptor implements Cloneable {
 \r
         public BinaryRC4CipherInputStream(DocumentInputStream stream, long size)\r
                 throws GeneralSecurityException {\r
-            super(stream, size, _chunkSize);\r
+            super(stream, size, chunkSize);\r
         }\r
 \r
         public BinaryRC4CipherInputStream(InputStream stream)\r
                 throws GeneralSecurityException {\r
-            super(stream, Integer.MAX_VALUE, _chunkSize);\r
+            super(stream, Integer.MAX_VALUE, chunkSize);\r
         }    \r
     }\r
 \r
@@ -134,8 +134,8 @@ public class BinaryRC4Decryptor extends Decryptor implements Cloneable {
     public ChunkedCipherInputStream getDataStream(DirectoryNode dir) throws IOException,\r
             GeneralSecurityException {\r
         DocumentInputStream dis = dir.createDocumentInputStream(DEFAULT_POIFS_ENTRY);\r
-        _length = dis.readLong();\r
-        return new BinaryRC4CipherInputStream(dis, _length);\r
+        length = dis.readLong();\r
+        return new BinaryRC4CipherInputStream(dis, length);\r
     }\r
     \r
     @Override\r
@@ -147,16 +147,16 @@ public class BinaryRC4Decryptor extends Decryptor implements Cloneable {
 \r
     @Override\r
     public long getLength() {\r
-        if (_length == -1L) {\r
+        if (length == -1L) {\r
             throw new IllegalStateException("Decryptor.getDataStream() was not called");\r
         }\r
         \r
-        return _length;\r
+        return length;\r
     }\r
 \r
     @Override\r
     public void setChunkSize(int chunkSize) {\r
-        _chunkSize = chunkSize;\r
+        this.chunkSize = chunkSize;\r
     }\r
     \r
     @Override\r
index 9545cbab05881add8e9b03ac16de93943089035c..15bb476ea98e9af740f62489aa87609c4e607df2 100644 (file)
@@ -41,7 +41,7 @@ import org.apache.poi.util.LittleEndianByteArrayOutputStream;
 \r
 public class BinaryRC4Encryptor extends Encryptor implements Cloneable {\r
 \r
-    private int _chunkSize = 512;\r
+    private int chunkSize = 512;\r
     \r
     protected BinaryRC4Encryptor() {\r
     }\r
@@ -115,7 +115,7 @@ public class BinaryRC4Encryptor extends Encryptor implements Cloneable {
 \r
     @Override\r
     public void setChunkSize(int chunkSize) {\r
-        _chunkSize = chunkSize;\r
+        this.chunkSize = chunkSize;\r
     }\r
     \r
     @Override\r
@@ -127,12 +127,12 @@ public class BinaryRC4Encryptor extends Encryptor implements Cloneable {
 \r
         public BinaryRC4CipherOutputStream(OutputStream stream)\r
         throws IOException, GeneralSecurityException {\r
-            super(stream, BinaryRC4Encryptor.this._chunkSize);\r
+            super(stream, BinaryRC4Encryptor.this.chunkSize);\r
         }\r
 \r
         public BinaryRC4CipherOutputStream(DirectoryNode dir)\r
         throws IOException, GeneralSecurityException {\r
-            super(dir, BinaryRC4Encryptor.this._chunkSize);\r
+            super(dir, BinaryRC4Encryptor.this.chunkSize);\r
         }\r
 \r
         @Override\r
index 451708c6ef5c5154eec63564e0e7fea97f631b13..e781c9d894b1bea9465891e44b5e6218b2cc115b 100644 (file)
@@ -50,8 +50,8 @@ import org.apache.poi.util.StringUtil;
 \r
 public class CryptoAPIDecryptor extends Decryptor implements Cloneable {\r
 \r
-    private long _length;\r
-    private int _chunkSize = -1;\r
+    private long length = -1L;\r
+    private int chunkSize = -1;\r
     \r
     static class StreamDescriptorEntry {\r
         static BitField flagStream = BitFieldFactory.getInstance(1);\r
@@ -65,7 +65,6 @@ public class CryptoAPIDecryptor extends Decryptor implements Cloneable {
     }\r
 \r
     protected CryptoAPIDecryptor() {\r
-        _length = -1L;\r
     }\r
 \r
     @Override\r
@@ -209,14 +208,14 @@ public class CryptoAPIDecryptor extends Decryptor implements Cloneable {
      */\r
     @Override\r
     public long getLength() {\r
-        if (_length == -1L) {\r
+        if (length == -1L) {\r
             throw new IllegalStateException("Decryptor.getDataStream() was not called");\r
         }\r
-        return _length;\r
+        return length;\r
     }\r
 \r
     public void setChunkSize(int chunkSize) {\r
-        _chunkSize = chunkSize;\r
+        this.chunkSize = chunkSize;\r
     }\r
     \r
     @Override\r
@@ -234,7 +233,7 @@ public class CryptoAPIDecryptor extends Decryptor implements Cloneable {
 \r
         public CryptoAPICipherInputStream(InputStream stream, long size, int initialPos)\r
                 throws GeneralSecurityException {\r
-            super(stream, size, _chunkSize, initialPos);\r
+            super(stream, size, chunkSize, initialPos);\r
         }    \r
     }\r
 }\r
index 6bf04871dc46af57e91b3d40d4d7cc6d80b2d4aa..5fa9564a41cb5a3dad77e1a98174c0796dbed6ba 100644 (file)
@@ -29,13 +29,13 @@ import org.apache.poi.util.Internal;
  */
 @Internal
 /* package */ class CryptoAPIDocumentOutputStream extends ByteArrayOutputStream {
-    private Cipher cipher;
-    private CryptoAPIEncryptor encryptor;
-    private byte oneByte[] = { 0 };
+    private final Cipher cipher;
+    private final CryptoAPIEncryptor encryptor;
+    private final byte oneByte[] = { 0 };
 
     public CryptoAPIDocumentOutputStream(CryptoAPIEncryptor encryptor) throws GeneralSecurityException {
         this.encryptor = encryptor;
-        setBlock(0);
+        cipher = encryptor.initCipherForBlock(null, 0);
     }
     
     public byte[] getBuf() {
@@ -47,7 +47,7 @@ import org.apache.poi.util.Internal;
     }
     
     public void setBlock(int block) throws GeneralSecurityException {
-        cipher = encryptor.initCipherForBlock(cipher, block);
+        encryptor.initCipherForBlock(cipher, block);
     }
     
     @Override
index e155584059de2569d0d9e1429de16de83912ae7d..d04096c3970d7fc394f861c9c1795937cd26c9b0 100644 (file)
@@ -53,7 +53,7 @@ import org.apache.poi.util.StringUtil;
 \r
 public class CryptoAPIEncryptor extends Encryptor implements Cloneable {\r
     \r
-    private int _chunkSize = 512;\r
+    private int chunkSize = 512;\r
     \r
     protected CryptoAPIEncryptor() {\r
     }\r
@@ -215,7 +215,7 @@ public class CryptoAPIEncryptor extends Encryptor implements Cloneable {
 \r
     @Override\r
     public void setChunkSize(int chunkSize) {\r
-        _chunkSize = chunkSize;\r
+        this.chunkSize = chunkSize;\r
     }\r
     \r
     protected void createEncryptionInfoEntry(DirectoryNode dir) throws IOException {\r
@@ -259,12 +259,12 @@ public class CryptoAPIEncryptor extends Encryptor implements Cloneable {
         @Override\r
         protected void createEncryptionInfoEntry(DirectoryNode dir, File tmpFile)\r
         throws IOException, GeneralSecurityException {\r
-            throw new RuntimeException("createEncryptionInfoEntry not supported");\r
+            throw new EncryptedDocumentException("createEncryptionInfoEntry not supported");\r
         }\r
 \r
         public CryptoAPICipherOutputStream(OutputStream stream)\r
         throws IOException, GeneralSecurityException {\r
-            super(stream, CryptoAPIEncryptor.this._chunkSize);\r
+            super(stream, CryptoAPIEncryptor.this.chunkSize);\r
         }\r
 \r
         @Override\r
index 01725f48b461114631b70475e880e1d7c62fced4..3eb66b549e4e5d0ce436ab682aa8ec2c6dc5e0f5 100644 (file)
@@ -25,6 +25,7 @@ import javax.crypto.Cipher;
 import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;
 
+import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.poifs.crypt.ChunkedCipherInputStream;
 import org.apache.poi.poifs.crypt.CryptoFunctions;
 import org.apache.poi.poifs.crypt.Decryptor;
@@ -33,8 +34,8 @@ import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.util.LittleEndian;
 
 public class XORDecryptor extends Decryptor implements Cloneable {
-    private long _length = -1L;
-    private int _chunkSize = 512;
+    private long length = -1L;
+    private int chunkSize = 512;
 
     protected XORDecryptor() {
     }
@@ -69,7 +70,7 @@ public class XORDecryptor extends Decryptor implements Cloneable {
 
     @Override
     public ChunkedCipherInputStream getDataStream(DirectoryNode dir) throws IOException, GeneralSecurityException {
-        throw new RuntimeException("not supported");
+        throw new EncryptedDocumentException("not supported");
     }
 
     @Override
@@ -81,16 +82,16 @@ public class XORDecryptor extends Decryptor implements Cloneable {
 
     @Override
     public long getLength() {
-        if (_length == -1L) {
+        if (length == -1L) {
             throw new IllegalStateException("Decryptor.getDataStream() was not called");
         }
 
-        return _length;
+        return length;
     }
 
     @Override
     public void setChunkSize(int chunkSize) {
-        _chunkSize = chunkSize;
+        this.chunkSize = chunkSize;
     }
     
     @Override
@@ -99,14 +100,14 @@ public class XORDecryptor extends Decryptor implements Cloneable {
     }
 
     private class XORCipherInputStream extends ChunkedCipherInputStream {
-        private final int _initialOffset;
-        private int _recordStart = 0;
-        private int _recordEnd = 0;
+        private final int initialOffset;
+        private int recordStart = 0;
+        private int recordEnd = 0;
         
         public XORCipherInputStream(InputStream stream, int initialPos)
                 throws GeneralSecurityException {
-            super(stream, Integer.MAX_VALUE, _chunkSize);
-            _initialOffset = initialPos;
+            super(stream, Integer.MAX_VALUE, chunkSize);
+            this.initialOffset = initialPos;
         }
         
         @Override
@@ -133,9 +134,9 @@ public class XORDecryptor extends Decryptor implements Cloneable {
              * the time we are about to write each of the bytes of the record data.
              * This (the value) is then incremented after each byte is written. 
              */
-            final int xorArrayIndex = _initialOffset+_recordEnd+(pos-_recordStart);
+            final int xorArrayIndex = initialOffset+recordEnd+(pos-recordStart);
             
-            for (int i=0; pos+i < _recordEnd && i < totalBytes; i++) {
+            for (int i=0; pos+i < recordEnd && i < totalBytes; i++) {
                 // The following is taken from the Libre Office implementation
                 // It seems that the encrypt and decrypt method is mixed up
                 // in the MS-OFFCRYPTO docs
@@ -165,8 +166,8 @@ public class XORDecryptor extends Decryptor implements Cloneable {
             final int pos = (int)getPos();
             final byte chunk[] = getChunk();
             final int chunkMask = getChunkMask();
-            _recordStart = pos;
-            _recordEnd = _recordStart+recordSize;
+            recordStart = pos;
+            recordEnd = recordStart+recordSize;
             int nextBytes = Math.min(recordSize, chunk.length-(pos & chunkMask));
             invokeCipher(nextBytes, true);
         }
index 388e3d8727c341735b9ee3762beb0b1d3028caea..ba0645cb775b009010cbc60e564797c58bb0de5c 100644 (file)
@@ -60,12 +60,12 @@ public class XOREncryptionVerifier extends EncryptionVerifier implements Encrypt
     }
 
     @Override
-    protected void setEncryptedVerifier(byte[] encryptedVerifier) {
+    protected final void setEncryptedVerifier(byte[] encryptedVerifier) {
         super.setEncryptedVerifier(encryptedVerifier);
     }
 
     @Override
-    protected void setEncryptedKey(byte[] encryptedKey) {
+    protected final void setEncryptedKey(byte[] encryptedKey) {
         super.setEncryptedKey(encryptedKey);
     }
 }
index 4a0b48801870c38d34bb9c0f4eef01b1082d85ba..1c0834c8ca767866bd2776cd28566e8cb31965f6 100644 (file)
@@ -61,8 +61,7 @@ public class XOREncryptor extends Encryptor implements Cloneable {
     @Override
     public OutputStream getDataStream(DirectoryNode dir)
     throws IOException, GeneralSecurityException {
-        OutputStream countStream = new XORCipherOutputStream(dir);
-        return countStream;
+        return new XORCipherOutputStream(dir);
     }
 
     @Override
@@ -89,19 +88,15 @@ public class XOREncryptor extends Encryptor implements Cloneable {
     }
 
     private class XORCipherOutputStream extends ChunkedCipherOutputStream {
-        private final int _initialOffset;
-        private int _recordStart = 0;
-        private int _recordEnd = 0;
-        private boolean _isPlain = false;
+        private int recordStart = 0;
+        private int recordEnd = 0;
 
         public XORCipherOutputStream(OutputStream stream, int initialPos) throws IOException, GeneralSecurityException {
             super(stream, -1);
-            _initialOffset = initialPos;
         }
 
         public XORCipherOutputStream(DirectoryNode dir) throws IOException, GeneralSecurityException {
             super(dir, -1);
-            _initialOffset = 0;
         }
 
         @Override
@@ -122,13 +117,12 @@ public class XOREncryptor extends Encryptor implements Cloneable {
 
         @Override
         public void setNextRecordSize(int recordSize, boolean isPlain) {
-            if (_recordEnd > 0 && !_isPlain) {
+            if (recordEnd > 0 && !isPlain) {
                 // encrypt last record
                 invokeCipher((int)getPos(), true);
             }
-            _recordStart = (int)getTotalPos()+4;
-            _recordEnd = _recordStart+recordSize;
-            _isPlain = isPlain;
+            recordStart = (int)getTotalPos()+4;
+            recordEnd = recordStart+recordSize;
         }
 
         @Override
@@ -143,7 +137,7 @@ public class XOREncryptor extends Encryptor implements Cloneable {
                 return 0;
             }
 
-            final int start = Math.max(posInChunk-(_recordEnd-_recordStart), 0);
+            final int start = Math.max(posInChunk-(recordEnd-recordStart), 0);
 
             final BitSet plainBytes = getPlainByteFlags();
             final byte xorArray[] = getEncryptionInfo().getEncryptor().getSecretKey().getEncoded();
@@ -161,7 +155,7 @@ public class XOREncryptor extends Encryptor implements Cloneable {
              * This (the value) is then incremented after each byte is written.
              */
             // ... also need to handle invocation in case of a filled chunk
-            int xorArrayIndex = _recordEnd+(start-_recordStart);
+            int xorArrayIndex = recordEnd+(start-recordStart);
 
             for (int i=start; i < posInChunk; i++) {
                 byte value = chunk[i];
index e6a77f854efa4d8f777e895e1c5769d0de36ca6b..e1b94b64e93b4f3c4491131f8451f5aee4ef93a7 100644 (file)
@@ -573,8 +573,7 @@ public class POIXMLDocumentPart {
             }
             
             // Default to searching from 1, unless they asked for 0+
-            int idx = minIdx;
-            if (minIdx < 0) idx = 1;
+            int idx = (minIdx < 0) ? 1 : minIdx;
             int maxIdx = minIdx + pkg.getParts().size();
             while (idx <= maxIdx) {
                 name = descriptor.getFileName(idx);
index ffe0cdf3f79c90ad52b6cf6556e8973614605d38..0263790df644ab449f1415545332ab4de439c575 100644 (file)
@@ -312,7 +312,7 @@ public class AgileDecryptor extends Decryptor implements Cloneable {
         } else {
             aps = new IvParameterSpec(iv);
         }
-            
+
         existing.init(encryptionMode, skey, aps);
         
         return existing;
index 6d9ec6d66f7896f9654c624f903cd554fe5539ef..186b27da50158e4a1e1252d6d97257250ebf9b20 100644 (file)
@@ -21,7 +21,6 @@ import java.security.GeneralSecurityException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
 
@@ -68,11 +67,11 @@ public class AgileEncryptionVerifier extends EncryptionVerifier implements Clone
             throw new EncryptedDocumentException("Unable to parse keyData", e);
         }
         
-        int keyBits = (int)keyData.getKeyBits();
-        CipherAlgorithm ca = CipherAlgorithm.fromXmlId(keyData.getCipherAlgorithm().toString(), keyBits);
+        int kb = (int)keyData.getKeyBits();
+        CipherAlgorithm ca = CipherAlgorithm.fromXmlId(keyData.getCipherAlgorithm().toString(), kb);
         setCipherAlgorithm(ca);
 
-        setKeySize(keyBits);
+        setKeySize(kb);
         
         int blockSize = keyData.getBlockSize();
         setBlockSize(blockSize);
@@ -230,7 +229,7 @@ public class AgileEncryptionVerifier extends EncryptionVerifier implements Clone
     }
 
     @Override
-    protected void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm) {
+    protected final void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm) {
         super.setCipherAlgorithm(cipherAlgorithm);
         if (cipherAlgorithm.allowedKeySize.length == 1) {
             setKeySize(cipherAlgorithm.defaultKeySize);
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/temp/AesZipFileZipEntrySource.java b/src/ooxml/java/org/apache/poi/poifs/crypt/temp/AesZipFileZipEntrySource.java
new file mode 100644 (file)
index 0000000..5e1f4b3
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ *  ====================================================================
+ *    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.poifs.crypt.temp;
+
+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.poifs.crypt.ChainingMode;
+import org.apache.poi.poifs.crypt.CipherAlgorithm;
+import org.apache.poi.poifs.crypt.CryptoFunctions;
+import org.apache.poi.util.Beta;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.TempFile;
+
+/**
+ * An example <code>ZipEntrySource</code> that has encrypted temp files to ensure that
+ * sensitive data is not stored in raw format on disk.
+ */
+@Beta
+public class AesZipFileZipEntrySource implements ZipEntrySource {
+    private static POILogger LOG = POILogFactory.getLogger(AesZipFileZipEntrySource.class);
+    
+    private final File tmpFile;
+    private final ZipFile zipFile;
+    private final Cipher ci;
+    private 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!
+     */
+    @Override
+    public Enumeration<? extends ZipEntry> getEntries() {
+        return zipFile.entries();
+    }
+    
+    @Override
+    public InputStream getInputStream(ZipEntry entry) throws IOException {
+        InputStream is = zipFile.getInputStream(entry);
+        return new CipherInputStream(is, ci);
+    }
+    
+    @Override
+    public void close() throws IOException {
+        if(!closed) {
+            zipFile.close();
+            if (!tmpFile.delete()) {
+                LOG.log(POILogger.WARN, tmpFile.getAbsolutePath()+" can't be removed (or was already removed.");
+            };
+        }
+        closed = true;
+    }
+
+    @Override
+    public boolean isClosed() {
+        return closed;
+    }
+
+    public static AesZipFileZipEntrySource 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
+                @Override
+                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 AesZipFileZipEntrySource 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);
+    }
+    
+}
\ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/temp/EncryptedTempData.java b/src/ooxml/java/org/apache/poi/poifs/crypt/temp/EncryptedTempData.java
new file mode 100644 (file)
index 0000000..7a3981d
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ *  ====================================================================
+ *    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.poifs.crypt.temp;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+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.poifs.crypt.ChainingMode;
+import org.apache.poi.poifs.crypt.CipherAlgorithm;
+import org.apache.poi.poifs.crypt.CryptoFunctions;
+import org.apache.poi.util.Beta;
+import org.apache.poi.util.Internal;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.TempFile;
+
+/**
+ * EncryptedTempData can be used to buffer binary data in a secure way, by using encrypted temp files.
+ */
+@Beta
+public class EncryptedTempData {
+    private static POILogger LOG = POILogFactory.getLogger(EncryptedTempData.class);
+    private final static CipherAlgorithm cipherAlgorithm = CipherAlgorithm.aes128;
+    private final SecretKeySpec skeySpec;
+    private final byte[] ivBytes;
+    private final File tempFile;
+    
+    public EncryptedTempData() throws IOException {
+        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);
+        tempFile = TempFile.createTempFile("poi-temp-data", ".tmp");
+    }
+
+    public OutputStream getOutputStream() throws IOException {
+        Cipher ciEnc = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.ENCRYPT_MODE, null);
+        return new CipherOutputStream(new FileOutputStream(tempFile), ciEnc);
+    }
+
+    public InputStream getInputStream() throws IOException {
+        Cipher ciDec = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.DECRYPT_MODE, null);
+        return new CipherInputStream(new FileInputStream(tempFile), ciDec);
+    }
+    
+    public void dispose() {
+        if (!tempFile.delete()) {
+            LOG.log(POILogger.WARN, tempFile.getAbsolutePath()+" can't be removed (or was already removed.");
+        }
+    }
+}
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/temp/SXSSFWorkbookWithCustomZipEntrySource.java b/src/ooxml/java/org/apache/poi/poifs/crypt/temp/SXSSFWorkbookWithCustomZipEntrySource.java
new file mode 100644 (file)
index 0000000..5460068
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  ====================================================================
+ *    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.poifs.crypt.temp;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.GeneralSecurityException;
+
+import org.apache.poi.openxml4j.util.ZipEntrySource;
+import org.apache.poi.util.Beta;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.streaming.SheetDataWriter;
+
+@Beta
+public class SXSSFWorkbookWithCustomZipEntrySource extends SXSSFWorkbook {
+    private static final POILogger LOG = POILogFactory.getLogger(SXSSFWorkbookWithCustomZipEntrySource.class);
+
+    public SXSSFWorkbookWithCustomZipEntrySource() {
+        super(20);
+        setCompressTempFiles(true);
+    }
+    
+    @Override
+    public void write(OutputStream stream) throws IOException {
+        flushSheets();
+        EncryptedTempData tempData = new EncryptedTempData();
+        ZipEntrySource source = null;
+        try {
+            OutputStream os = tempData.getOutputStream();
+            try {
+                getXSSFWorkbook().write(os);
+            } finally {
+                IOUtils.closeQuietly(os);
+            }
+            // provide ZipEntrySource to poi which decrypts on the fly
+            source = AesZipFileZipEntrySource.createZipEntrySource(tempData.getInputStream());
+            injectData(source, stream);
+        } catch (GeneralSecurityException e) {
+            throw new IOException(e);
+        } finally {
+            tempData.dispose();
+            IOUtils.closeQuietly(source);
+        }
+    }
+    
+    @Override
+    protected SheetDataWriter createSheetDataWriter() throws IOException {
+        //log values to ensure these values are accessible to subclasses
+        LOG.log(POILogger.INFO, "isCompressTempFiles: " + isCompressTempFiles());
+        LOG.log(POILogger.INFO, "SharedStringSource: " + getSharedStringSource());
+        return new SheetDataWriterWithDecorator();
+    }
+}
diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/temp/SheetDataWriterWithDecorator.java b/src/ooxml/java/org/apache/poi/poifs/crypt/temp/SheetDataWriterWithDecorator.java
new file mode 100644 (file)
index 0000000..08163ea
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  ====================================================================
+ *    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.poifs.crypt.temp;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+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.poifs.crypt.ChainingMode;
+import org.apache.poi.poifs.crypt.CipherAlgorithm;
+import org.apache.poi.poifs.crypt.CryptoFunctions;
+import org.apache.poi.util.Beta;
+import org.apache.poi.xssf.streaming.SheetDataWriter;
+
+@Beta
+public 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);
+    }
+}
index 2accb026571507f3fcf66e0edb529f56b0f5d869..71942a1324e2be53b0e5900a3bf67e9319037659 100644 (file)
@@ -230,9 +230,8 @@ public class XSSFReader {
                 List<CTSheet> validSheets = new ArrayList<CTSheet>();
                 for (CTSheet ctSheet : wbBean.getSheets().getSheetList()) {
                     //if there's no relationship id, silently skip the sheet
-                     if ("".equals(ctSheet.getId())) {
-                        //skip it
-                    } else {
+                    String sheetId = ctSheet.getId();
+                    if (sheetId != null && sheetId.length() > 0) {
                         validSheets.add(ctSheet);
                     }
                 }
index 30c54b910e61a65aa523d881557216cc6b1e2266..9820ddd0f94ec8b7e1a8468f3d16cd052031a8c5 100644 (file)
@@ -127,7 +127,7 @@ public class SheetDataWriter {
         _out.close();\r
     }\r
 \r
-    File getTempFile(){\r
+    protected File getTempFile(){\r
         return _fd;\r
     }\r
     \r
index 682b1cfd48aab3c532892e57eb8d84737d25417f..68799fdca556a38e9abde45cd4ef34ebadda35aa 100644 (file)
@@ -16,8 +16,6 @@
 ==================================================================== */
 package org.apache.poi.xwpf.model;
 
-import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
-
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.POIXMLDocumentPart.RelationPart;
 import org.apache.poi.util.POILogFactory;
@@ -65,8 +63,6 @@ import com.microsoft.schemas.vml.STTrueFalse;
  * the right headers and footers for the document.
  */
 public class XWPFHeaderFooterPolicy {
-    private static final POILogger LOG = POILogFactory.getLogger(XWPFHeaderFooterPolicy.class);
-    
     public static final Enum DEFAULT = STHdrFtr.DEFAULT;
     public static final Enum EVEN = STHdrFtr.EVEN;
     public static final Enum FIRST = STHdrFtr.FIRST;
@@ -282,7 +278,7 @@ public class XWPFHeaderFooterPolicy {
                 CTP p = ftr.addNewP();
                 ftr.setPArray(i, paragraphs[i].getCTP());
             }
-        } else {
+//        } else {
 //            CTP p = ftr.addNewP();
 //            CTBody body = doc.getDocument().getBody();
 //            if (body.sizeOfPArray() > 0) {
index eb9da3c332678d64f524be8569ac85b4197e4e89..9afde2caf6c74831dddcbd7a26cbed619c2e37be 100644 (file)
@@ -449,7 +449,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
                 CTOnOff titlePg = ctSectPr.addNewTitlePg();
                 titlePg.setVal(STOnOff.ON);
             }
-        } else if (type == HeaderFooterType.EVEN) {
+        // } else if (type == HeaderFooterType.EVEN) {
             // TODO Add support for Even/Odd headings and footers
         }
         return hfPolicy.createHeader(STHdrFtr.Enum.forInt(type.toInt()));
@@ -471,7 +471,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
                 CTOnOff titlePg = ctSectPr.addNewTitlePg();
                 titlePg.setVal(STOnOff.ON);
             }
-        } else if (type == HeaderFooterType.EVEN) {
+        // } else if (type == HeaderFooterType.EVEN) {
             // TODO Add support for Even/Odd headings and footers
         }
         return hfPolicy.createFooter(STHdrFtr.Enum.forInt(type.toInt()));
diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/AesZipFileZipEntrySource.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/AesZipFileZipEntrySource.java
deleted file mode 100644 (file)
index 4582c2f..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/* ====================================================================
-   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.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!
-     */
-    @Override
-    public Enumeration<? extends ZipEntry> getEntries() {
-        return zipFile.entries();
-    }
-
-    @Override
-    @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 {
-        if(!closed) {
-            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
-                @Override
-                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);
-    }
-
-}
-
index 77ae0033ab8496324684c47dad05240ee7bcc78d..e6224adf4e4f5f3e8a9637711867ee9884a4b775 100644 (file)
@@ -29,6 +29,7 @@ import java.security.GeneralSecurityException;
 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.crypt.temp.AesZipFileZipEntrySource;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.xssf.XSSFTestDataSamples;
 import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor;
index 6c5a6c87e3dbc1c027b5b3107cc63c08ded94a74..cb90efb321b2b3d24d30082bb402fdcf11da0103 100644 (file)
@@ -21,8 +21,8 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.poi.xssf.streaming.TestSXSSFWorkbookWithCustomZipEntrySource.SXSSFWorkbookWithCustomZipEntrySource;
-import org.apache.poi.xssf.streaming.TestSXSSFWorkbookWithCustomZipEntrySource.SheetDataWriterWithDecorator;
+import org.apache.poi.poifs.crypt.temp.SXSSFWorkbookWithCustomZipEntrySource;
+import org.apache.poi.poifs.crypt.temp.SheetDataWriterWithDecorator;
 
 // a class to record a list of temporary files that are written to disk
 // afterwards, a test function can check whether these files were encrypted or not
index 7523f775e47205592c61de332861ae397fd89a8b..b477c8b10273bf97aa53557a4b2ae7be20183115 100644 (file)
@@ -27,31 +27,19 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
 import java.nio.charset.Charset;
 import java.security.GeneralSecurityException;
-import java.security.SecureRandom;
 import java.util.List;
 
-import javax.crypto.Cipher;
-import javax.crypto.CipherInputStream;
-import javax.crypto.CipherOutputStream;
-import javax.crypto.spec.SecretKeySpec;
-
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 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.poifs.crypt.temp.AesZipFileZipEntrySource;
+import org.apache.poi.poifs.crypt.temp.EncryptedTempData;
+import org.apache.poi.poifs.crypt.temp.SXSSFWorkbookWithCustomZipEntrySource;
 import org.apache.poi.util.IOUtils;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
-import org.apache.poi.util.TempFile;
 import org.apache.poi.xssf.usermodel.XSSFCell;
 import org.apache.poi.xssf.usermodel.XSSFRow;
 import org.apache.poi.xssf.usermodel.XSSFSheet;
@@ -145,104 +133,4 @@ public final class TestSXSSFWorkbookWithCustomZipEntrySource {
         workbook.dispose();
         assertFalse("tempFile deleted after dispose?", tempFile.exists());
     }
-    
-    static class SXSSFWorkbookWithCustomZipEntrySource extends SXSSFWorkbook {
-
-        private static final POILogger logger = POILogFactory.getLogger(SXSSFWorkbookWithCustomZipEntrySource.class);
-
-        @Override
-        public void write(OutputStream stream) throws IOException {
-            flushSheets();
-            EncryptedTempData tempData = new EncryptedTempData();
-            OutputStream os = tempData.getOutputStream();
-            getXSSFWorkbook().write(os);
-            os.close();
-            ZipEntrySource source = null;
-            try {
-                // provide ZipEntrySource to poi which decrypts on the fly
-                source = AesZipFileZipEntrySource.createZipEntrySource(tempData.getInputStream());
-                injectData(source, stream);
-            } catch (GeneralSecurityException e) {
-                throw new IOException(e);
-            } finally {
-                tempData.dispose();
-                IOUtils.closeQuietly(source);
-            }
-        }
-
-        @Override
-        protected SheetDataWriter createSheetDataWriter() throws IOException {
-            //log values to ensure these values are accessible to subclasses
-            logger.log(POILogger.INFO, "isCompressTempFiles: " + isCompressTempFiles());
-            logger.log(POILogger.INFO, "SharedStringSource: " + getSharedStringSource());
-            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);
-        }
-    }
-    
-    // a class to save and read an AES-encrypted workbook
-    static class EncryptedTempData {
-        final static CipherAlgorithm cipherAlgorithm = CipherAlgorithm.aes128;
-        final SecretKeySpec skeySpec;
-        final byte[] ivBytes;
-        final File tempFile;
-        
-        EncryptedTempData() throws IOException {
-            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);
-            tempFile = TempFile.createTempFile("poi-temp-data", ".tmp");
-        }
-
-        OutputStream getOutputStream() throws IOException {
-            Cipher ciEnc = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.ENCRYPT_MODE, null);
-            return new CipherOutputStream(new FileOutputStream(tempFile), ciEnc);
-        }
-
-        InputStream getInputStream() throws IOException {
-            Cipher ciDec = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.DECRYPT_MODE, null);
-            return new CipherInputStream(new FileInputStream(tempFile), ciDec);
-        }
-        
-        void dispose() {
-            assertTrue("Could not delete tempfile " + tempFile + ": " + tempFile.exists(),
-                    !tempFile.exists() || tempFile.delete());
-        }
-    }
-}
+}
\ No newline at end of file
index 6873d75995969f553371467e6f2959f6e40ddc4d..6eaf0d44ece4799b4641e55d0bc0ace5888241cc 100644 (file)
@@ -28,14 +28,24 @@ public final class PointerV5 extends Pointer {
         return (0x40 <= format && format < 0x50);
     }
     public boolean destinationHasPointers() {
-        if(type == 20) return true;
-        if(type == 22) return false;
-        if(format == 0x1d || format == 0x1e) return true;
+        if(type == 20) {
+            return true;
+        }
+        if(type == 22) {
+            return false;
+        }
+        if(format == 0x1d || format == 0x1e) {
+            return true;
+        }
         return (0x50 <= format && format < 0x60);
     }
     public boolean destinationHasChunks() {
-        if (type == 21) return true;
-        if (type == 24) return true;
+        if (type == 21) {
+            return true;
+        }
+        if (type == 24) {
+            return true;
+        }
         return (0xd0 <= format && format < 0xdf);
     }
 
index b0ce968e6b90b1e7ec62213d124caf902bc4ba1f..d68b4f70165ef48606600b60b72eea17f3d08b0f 100644 (file)
@@ -33,7 +33,7 @@ import org.apache.poi.util.Units;
  * Represents Macintosh PICT picture data.
  */
 public final class PICT extends Metafile {
-    private static POILogger LOG = POILogFactory.getLogger(PICT.class);
+    private static final POILogger LOG = POILogFactory.getLogger(PICT.class);
     
     public static class NativeHeader {
         /**
index 5e045f526ae4da8de4b50820c249930cd6d7276d..740d9532d7ce236ecc0e51225834882f82285c11 100644 (file)
@@ -346,7 +346,9 @@ public final class HSLFFreeformShape extends HSLFAutoShape implements FreeformSh
     }
     
     private void fillPoint(byte xyMaster[], double xyPoints[]) {
-        if (xyMaster == null || xyPoints == null || (xyMaster.length != 4 && xyMaster.length != 8) || xyPoints.length != 2) {
+        int masterCnt = (xyMaster == null) ? 0 : xyMaster.length;
+        int pointCnt = (xyPoints == null) ? 0 : xyPoints.length;
+        if ((masterCnt != 4 && masterCnt != 8) || pointCnt != 2) {
             logger.log(POILogger.WARN, "Invalid number of master bytes for a single point - ignore point");
             return;
         }