Bug 57080 - IndexOutOfBoundsException in poi decryptor

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1631600 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2014-10-13 23:42:33 +00:00
parent 8aab89c3ff
commit 860892e68d
3 changed files with 34 additions and 1 deletions

View File

@ -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(){

View File

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

Binary file not shown.