diff --git a/src/java/org/apache/poi/poifs/crypt/standard/StandardDecryptor.java b/src/java/org/apache/poi/poifs/crypt/standard/StandardDecryptor.java index a3bef188a..86e31fb7a 100644 --- a/src/java/org/apache/poi/poifs/crypt/standard/StandardDecryptor.java +++ b/src/java/org/apache/poi/poifs/crypt/standard/StandardDecryptor.java @@ -139,7 +139,15 @@ public class StandardDecryptor extends Decryptor { _length = dis.readLong(); - return new BoundedInputStream(new CipherInputStream(dis, getCipher(getSecretKey())), _length); + // limit wrong calculated ole entries - (bug #57080) + // standard encryption always uses aes encoding, so blockSize is always 16 + // http://stackoverflow.com/questions/3283787/size-of-data-after-aes-encryption + int blockSize = info.getHeader().getCipherAlgorithm().blockSize; + long cipherLen = (_length/blockSize + 1) * blockSize; + Cipher cipher = getCipher(getSecretKey()); + + InputStream boundedDis = new BoundedInputStream(dis, cipherLen); + return new BoundedInputStream(new CipherInputStream(boundedDis, cipher), _length); } public long getLength(){ diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java index 48bc7a15a..d0f2c67f5 100644 --- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java +++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java @@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.security.GeneralSecurityException; @@ -27,7 +29,9 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.poi.POIDataSamples; +import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.util.IOUtils; import org.junit.Test; /** @@ -122,4 +126,25 @@ public class TestDecryptor { } } + @Test + public void bug57080() throws Exception { + // the test file contains a wrong ole entry size, produced by extenxls + // the fix limits the available size and tries to read all entries + File f = POIDataSamples.getPOIFSInstance().getFile("extenxls_pwd123.xlsx"); + NPOIFSFileSystem fs = new NPOIFSFileSystem(f, true); + EncryptionInfo info = new EncryptionInfo(fs); + Decryptor d = Decryptor.getInstance(info); + d.verifyPassword("pwd123"); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ZipInputStream zis = new ZipInputStream(d.getDataStream(fs)); + ZipEntry ze; + while ((ze = zis.getNextEntry()) != null) { + bos.reset(); + IOUtils.copy(zis, bos); + assertEquals(ze.getSize(), bos.size()); + } + + zis.close(); + fs.close(); + } } \ No newline at end of file diff --git a/test-data/poifs/extenxls_pwd123.xlsx b/test-data/poifs/extenxls_pwd123.xlsx new file mode 100644 index 000000000..a6ae896f9 Binary files /dev/null and b/test-data/poifs/extenxls_pwd123.xlsx differ