I found there are some cases in which the protect, object protect, window protect BIFF records can contain no data, In most case this happen when protection is applied through vba routines with old Excel version. I think must be considered the option to set the protection flag if record is present but not contains data. For example the org.apache.poi.hssf.record.ProtectRecord class can be patched in this way: public ProtectRecord(RecordInputStream in) { this._options = 1; try { this._options = in.readShort(); } catch (RecordFormatException e) { //System.out.println("Wrong Protect record found, set and skip check "); } } or check for availability of data in RecordInputStream in. Best Regards Francesco Petruzzi Information Security Manager Innovery SpA
Hi Francesco, please can you provide a minimal unit test demonstrating the problem this patch is trying to solve? Are you saying you get an NPE or other exception trying to read such a file?
The file I use is confidential, I am waiting for a file free for distribution. If I load and save the file with Excel2007 the output file is ok. This is the stack trace when try to load ProtectRecord on original file: org.apache.poi.hssf.record.RecordFormatException: Not enough data (0) to read requested (2) bytes at org.apache.poi.hssf.record.RecordInputStream.checkRecordPosition(RecordInputStream.java:216) at org.apache.poi.hssf.record.RecordInputStream.readShort(RecordInputStream.java:233) at org.apache.poi.hssf.record.ProtectRecord.<init>(ProtectRecord.java:50) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at org.apache.poi.hssf.record.RecordFactory$ReflectionConstructorRecordCreator.create(RecordFactory.java:87) at org.apache.poi.hssf.record.RecordFactory.createSingleRecord(RecordFactory.java:338) at org.apache.poi.hssf.record.RecordFactoryInputStream.readNextRecord(RecordFactoryInputStream.java:310) at org.apache.poi.hssf.record.RecordFactoryInputStream.nextRecord(RecordFactoryInputStream.java:276) at org.apache.poi.hssf.record.RecordFactory.createRecords(RecordFactory.java:480) at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:326) at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:115) at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:172) at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:143) at eu.inn.xlsx.JExcelExport.doExportCSV(JExcelExport.java:198) at eu.inn.xlsx.JExcelExport.doExportCSV(JExcelExport.java:180) at eu.inn.ExcelToCSV.main(ExcelToCSV.java:314) eu.inn.xlsx.JExcelException: Error:161 Opening input Excel file: Not enough data (0) to read requested (2) bytes at eu.inn.xlsx.JExcelExport.doExportCSV(JExcelExport.java:231) at eu.inn.xlsx.JExcelExport.doExportCSV(JExcelExport.java:180) at eu.inn.ExcelToCSV.main(ExcelToCSV.java:314)
Without an example file, we can't reproduce the error and thus can't fix it and verify the fix.