Bug 63070 - sheet looping bug for encrypted XLS file
Summary: sheet looping bug for encrypted XLS file
Alias: None
Product: POI
Classification: Unclassified
Component: HSSF (show other bugs)
Version: 3.17-FINAL
Hardware: Other other
: P2 critical (vote)
Target Milestone: ---
Assignee: POI Developers List
Depends on:
Reported: 2019-01-08 22:59 UTC by Brian Yoder
Modified: 2019-01-09 20:04 UTC (History)
0 users


Note You need to log in before you can comment on or make changes to this bug.
Description Brian Yoder 2019-01-08 22:59:11 UTC
I have reproduced the issue with Apache POI 3.16 and 3.17. I have an encrypted document saved in XLS format, and it goes into an infinite loop of BOFRecord events (of type sheet). I know this because I have now converted to streaming API, and have set my own max counters in there to prevent very long loop.

My XLS file is sensitive in nature, so not sure I can provide it. But there should be some reasonable limits in POI (how may sheets, rows, workbooks) - so that it never goes into an infinite loop! I was actually able to processes the XLS file using the streaming API, and it says that there were 2,097,126 BOFRecord worksheet hits in the following event (sheetCount) - but when I open the file in Excel there are ONLY three sheets to be seen. So something is off, and POI thinks there are many more sheets than actually exist in the file.

Also, this happens on BOTH Windows and Linux under java 1.7_80

... CODE for XLS event processing

        switch (record.getSid())
            // the BOFRecord can represent either the beginning of a sheet or the workbook
            case BOFRecord.sid:
                BOFRecord bof = (BOFRecord) record;
                if (bof.getType() == bof.TYPE_WORKBOOK)
                	//if (workbookCount > MAX_WORKBOOKS) {
                	//	throw new RuntimeException("Max workbooks found!");
                    //System.out.println("Encountered workbook");
                    // assigned to the class level member
                } else if (bof.getType() == bof.TYPE_WORKSHEET)
                	//if (sheetCount > MAX_SHEETS) {
                	//	throw new RuntimeException("Max sheets found!");
                    //System.out.println("Encountered sheet reference");

Here is a stack of the Thread after it's been running a while. The file is only 40 KB, with not much data. It has only three sheets, so why it goes off into a seemingly endless loop of sheets is strange.

   java.lang.Thread.State: RUNNABLE
        at sun.reflect.Reflection.getCallerClass(Native Method)
        at java.lang.Class.getConstructor(Class.java:1730)
        at java.security.Provider$Service.newInstance(Provider.java:1239)
        at sun.security.jca.GetInstance.getInstance(GetInstance.java:236)
        at sun.security.jca.GetInstance.getInstance(GetInstance.java:164)
        at java.security.Security.getImpl(Security.java:695)
        at java.security.MessageDigest.getInstance(MessageDigest.java:167)
        at org.apache.poi.poifs.crypt.CryptoFunctions.getMessageDigest(CryptoFunctions.java:295)
        at org.apache.poi.poifs.crypt.CryptoFunctions.generateKey(CryptoFunctions.java:178)
        at org.apache.poi.poifs.crypt.binaryrc4.BinaryRC4Decryptor.initCipherForBlock(BinaryRC4Decryptor.java:101)
        at org.apache.poi.poifs.crypt.binaryrc4.BinaryRC4Decryptor.initCipherForBlock(BinaryRC4Decryptor.java:91)
        at org.apache.poi.poifs.crypt.binaryrc4.BinaryRC4Decryptor$BinaryRC4CipherInputStream.initCipherForBlock(BinaryRC4Decryptor.java:46)
        at org.apache.poi.poifs.crypt.ChunkedCipherInputStream.nextChunk(ChunkedCipherInputStream.java:178)
        at org.apache.poi.poifs.crypt.ChunkedCipherInputStream.read(ChunkedCipherInputStream.java:103)
        at org.apache.poi.poifs.crypt.ChunkedCipherInputStream.readPlain(ChunkedCipherInputStream.java:236)
        at org.apache.poi.hssf.record.crypto.Biff8DecryptingStream.readPlain(Biff8DecryptingStream.java:208)
        at org.apache.poi.hssf.record.crypto.Biff8DecryptingStream.readDataSize(Biff8DecryptingStream.java:89)
        at org.apache.poi.hssf.record.RecordInputStream.nextRecord(RecordInputStream.java:220)
        at org.apache.poi.hssf.record.RecordFactoryInputStream.nextRecord(RecordFactoryInputStream.java:253)
        at org.apache.poi.hssf.record.RecordFactory.createRecords(RecordFactory.java:494)
        at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:356)
Comment 1 PJ Fanning 2019-01-09 20:04:53 UTC
Could you try POI 4.0.1?

It would be useful for reproducibility of you could provide the xls file and a basic snippet of how you create the workbook.