Bug 65877 - Error while trying open a write protected xls file
Summary: Error while trying open a write protected xls file
Status: NEEDINFO
Alias: None
Product: POI
Classification: Unclassified
Component: HSSF (show other bugs)
Version: 5.2.0-FINAL
Hardware: PC All
: P2 major (vote)
Target Milestone: ---
Assignee: POI Developers List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-02-09 13:07 UTC by Debashish Sahu
Modified: 2022-02-21 17:27 UTC (History)
2 users (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Debashish Sahu 2022-02-09 13:07:22 UTC
Hi Team,

We are trying to parser protected xls files(files which can be opened in read-only mode using MS Excel Any version),with out the password.
These files are transferred during FTP and program tries to read the files as it comes.
While using the HSSF framework we are getting below error. 
We also observed that if files are opened once using any native app (E.g. MS Excel), before feeding it to program we are able to read the file successfully.

org.apache.poi.util.RecordFormatException: Unable to construct record instance
	at org.apache.poi.hssf.record.RecordFactory$ReflectionConstructorRecordCreator.create(RecordFactory.java:94)
	at org.apache.poi.hssf.record.RecordFactory.createSingleRecord(RecordFactory.java:339)
	at org.apache.poi.hssf.record.RecordFactoryInputStream.readNextRecord(RecordFactoryInputStream.java:289)
	at org.apache.poi.hssf.record.RecordFactoryInputStream.nextRecord(RecordFactoryInputStream.java:255)
	at org.apache.poi.hssf.record.RecordFactory.createRecords(RecordFactory.java:488)
	at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:343)
	at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:306)
	at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:258)
	at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:241)
	at com.highradius.arpa.textextraction.ExcelReadUsingPoi.readV1(ExcelReadUsingPoi.java:31)
	at com.highradius.arpa.textextraction.ExcelReadUsingPoi.main(ExcelReadUsingPoi.java:20)
Caused by: java.lang.IllegalArgumentException: Name is too long: 5??i??$????+????	&
H???4|?|?o???????0??%Z[=?[/h???>?I8v??|/"?\f???.?[?????Z?????v?V???R???5?
	at org.apache.poi.hssf.record.WriteAccessRecord.setUsername(WriteAccessRecord.java:107)
	at org.apache.poi.hssf.record.WriteAccessRecord.<init>(WriteAccessRecord.java:75)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.apache.poi.hssf.record.RecordFactory$ReflectionConstructorRecordCreator.create(RecordFactory.java:84)

Code : 

private static void readPOIV1(File file) throws FileNotFoundException, IOException {
		HSSFWorkbook wbxls = null; // for xls
		System.out.println("readPOIV1 Trying to read file - " + file.getAbsolutePath());
		POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(file));
		wbxls = new HSSFWorkbook(fs);
		String readValue = wbxls.getSheetAt(1).getRow(0).getCell(1).getStringCellValue();
		System.out.println("readPOIV1 Read value from sheet#1 row#1 col#B - " + readValue);
}

On Further analysis we saw 

In a scenario where the file is directly fed to the program, the poi framework tries to intialize the WriteAccessRecord , and in function setUsername it fails as it tries to use the  hashed version of the user name.
It fails as there is a limit to the username length which is WriteAccessRecord.DATA_SIZE

We suggest to correct the logic and set a dummy user name , incase its not able to figure out the user name.
Comment 1 PJ Fanning 2022-02-09 13:25:18 UTC
You seem to be missing the step in your code to decrypt the password protected xls - I only really use XSSF and not HSSF, but as far as I can see you need a line like this:

Biff8EncryptionKey.setCurrentUserPassword("your-password");

I found this in this example - https://javacodepoint.com/how-to-read-password-protected-excel-in-java/
Comment 2 PJ Fanning 2022-02-09 13:27:09 UTC
If I am missing the point and you need a POI team to debug this - you will need to provide the xls file so that someone else can try to reproduce the issue.
Comment 3 PJ Fanning 2022-02-09 13:29:12 UTC
https://poi.apache.org/encryption.html is the page that describes the support for protected files
Comment 4 Debashish Sahu 2022-02-09 13:36:18 UTC
Point is we don't need the password , password is required only to open the file in write mode. 
Here we are try to open the file in read-only mode.

We are able to parse the file in read only mode using POI, after the file is opened at least once in the host machine native app (Windows - MS Excel).

We are expecting that using POI, we should be able to parse write protected excel files without having to open it once using native app.

We could have shared an example file, but as of now the files are internal in nature. we are trying to come up with a dummy test file
Comment 5 Andreas Beeker 2022-02-09 13:42:03 UTC
I can have a look at the file, If you are allowed to provide it to me privately.
Although only write-protected files aren't encrypted, it looks like the WriteAccess record doesn't cover all cases ...
If you can't provide the file, you might be able to extract that record, e.g. with my POI Visualizer (https://github.com/kiwiwings/poi-visualizer)