60881 and 60891 -- on further look, no need to throw an exception for an encrypted xlsb. On the second, let's fix readFully to read fully.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1787846 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Tim Allison 2017-03-20 20:47:15 +00:00
parent e4f884a915
commit 69c3311a98
4 changed files with 58 additions and 2 deletions

View File

@ -33,7 +33,7 @@ public class XSSFBFileHandler extends AbstractFileHandler {
static { static {
//add expected failures here: //add expected failures here:
// AbstractFileHandler.EXPECTED_EXTRACTOR_FAILURES.add("spreadsheet/Simple.xlsb"); AbstractFileHandler.EXPECTED_EXTRACTOR_FAILURES.add("spreadsheet/protected_passtika.xlsb");
} }
@Override @Override

View File

@ -28,6 +28,9 @@ import java.io.InputStream;
* by this class is consistent with that of the inner stream. * by this class is consistent with that of the inner stream.
*/ */
public class LittleEndianInputStream extends FilterInputStream implements LittleEndianInput { public class LittleEndianInputStream extends FilterInputStream implements LittleEndianInput {
private static final int EOF = -1;
public LittleEndianInputStream(InputStream is) { public LittleEndianInputStream(InputStream is) {
super(is); super(is);
} }
@ -128,12 +131,28 @@ public class LittleEndianInputStream extends FilterInputStream implements Little
@Override @Override
public void readFully(byte[] buf, int off, int len) { public void readFully(byte[] buf, int off, int len) {
try { try {
checkEOF(read(buf, off, len), len); checkEOF(_read(buf, off, len), len);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
//Makes repeated calls to super.read() until length is read or EOF is reached
private int _read(byte[] buffer, int offset, int length) throws IOException {
//lifted directly from org.apache.commons.io.IOUtils 2.4
int remaining = length;
while (remaining > 0) {
int location = length - remaining;
int count = read(buffer, offset + location, remaining);
if (EOF == count) { // EOF
break;
}
remaining -= count;
}
return length - remaining;
}
@Override @Override
public void readPlain(byte[] buf, int off, int len) { public void readPlain(byte[] buf, int off, int len) {
readFully(buf, off, len); readFully(buf, off, len);

View File

@ -32,6 +32,7 @@ import org.apache.poi.openxml4j.util.ZipEntrySource;
import org.apache.poi.poifs.crypt.temp.AesZipFileZipEntrySource; import org.apache.poi.poifs.crypt.temp.AesZipFileZipEntrySource;
import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.xssf.extractor.XSSFBEventBasedExcelExtractor;
import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor; import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
@ -79,4 +80,40 @@ public class TestSecureTempZip {
poifs.close(); poifs.close();
fis.close(); fis.close();
} }
/**
* Test case for #59841 - this is an example on how to use encrypted temp files,
* which are streamed into POI opposed to having everything in memory
*/
@Test
public void protectedXLSBZip() throws IOException, GeneralSecurityException, XmlException, OpenXML4JException {
File tikaProt = XSSFTestDataSamples.getSampleFile("protected_passtika.xlsb");
FileInputStream fis = new FileInputStream(tikaProt);
POIFSFileSystem poifs = new POIFSFileSystem(fis);
EncryptionInfo ei = new EncryptionInfo(poifs);
Decryptor dec = ei.getDecryptor();
boolean passOk = dec.verifyPassword("tika");
assertTrue(passOk);
// extract encrypted ooxml file and write to custom encrypted zip file
InputStream is = dec.getDataStream(poifs);
// provide ZipEntrySource to poi which decrypts on the fly
ZipEntrySource source = AesZipFileZipEntrySource.createZipEntrySource(is);
// test the source
OPCPackage opc = OPCPackage.open(source);
String expected = "You can't see me";
XSSFBEventBasedExcelExtractor extractor = new XSSFBEventBasedExcelExtractor(opc);
extractor.setIncludeSheetNames(false);
String txt = extractor.getText();
assertEquals(expected, txt.trim());
extractor.close();
opc.close();
poifs.close();
fis.close();
}
} }

Binary file not shown.