Bug 44695 - HSSF: Formulas are broken after re-save
Summary: HSSF: Formulas are broken after re-save
Alias: None
Product: POI
Classification: Unclassified
Component: HSSF (show other bugs)
Version: unspecified
Hardware: PC All
: P2 normal (vote)
Target Milestone: ---
Assignee: POI Developers List
Depends on:
Reported: 2008-03-27 11:30 UTC by Yegor Kozlov
Modified: 2008-03-27 13:15 UTC (History)
0 users

initial file (226.00 KB, application/vnd.ms-excel)
2008-03-27 11:31 UTC, Yegor Kozlov
saved by POI (226.00 KB, application/vnd.ms-excel)
2008-03-27 11:32 UTC, Yegor Kozlov
failing test (1.31 KB, application/octet-stream)
2008-03-27 11:33 UTC, Yegor Kozlov

Note You need to log in before you can comment on or make changes to this bug.
Description Yegor Kozlov 2008-03-27 11:30:49 UTC
Actually there are two problems:
 (1) In some cases formulas are broken after save. 
 (2) POI can't read the saved file with the broken formulas. I'm getting the following exception:

Exception in thread "main" org.apache.poi.hssf.record.RecordFormatException: Unable to construct record instance
	at org.apache.poi.hssf.record.RecordFactory.createRecord(RecordFactory.java:204)
	at org.apache.poi.hssf.record.RecordFactory.createRecords(RecordFactory.java:122)
	at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:204)
	at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:256)
	at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:237)
	at org.apache.poi.hssf.scratchpad.Scratchpad.main(Scratchpad.java:44)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at com.intellij.rt.execution.application.AppMain.main(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
	at org.apache.poi.hssf.record.RecordFactory.createRecord(RecordFactory.java:192)
	... 10 more
Caused by: java.lang.IllegalArgumentException: Illegal length 17478
	at org.apache.poi.hssf.record.RecordInputStream.readCompressedUnicode(RecordInputStream.java:270)
	at org.apache.poi.hssf.record.ExternalNameRecord.fillFields(ExternalNameRecord.java:162)
	at org.apache.poi.hssf.record.Record.<init>(Record.java:55)
	at org.apache.poi.hssf.record.ExternalNameRecord.<init>(ExternalNameRecord.java:54)
	... 15 more

This bug has appeared recently. The attached unit test passes with POI 3.0.2 but fails with trunk.

I attached a failing unit test and two files:

formulas.xls 		initial file with a formula in A1
formulas-saved.xls 	saved by POI. The formula in A1 is broken

It seems to be related to bug #44504. Josh, any ideas?  

Comment 1 Yegor Kozlov 2008-03-27 11:31:25 UTC
Created attachment 21723 [details]
initial file
Comment 2 Yegor Kozlov 2008-03-27 11:32:06 UTC
Created attachment 21724 [details]
saved by POI
Comment 3 Yegor Kozlov 2008-03-27 11:33:39 UTC
Created attachment 21725 [details]
failing test
Comment 4 Josh Micich 2008-03-27 13:15:41 UTC
Fixed in svn r641967/r641964

This was a problem in ExternalNameRecord.serialize(int, byte[]).  I originally
left a TODO in that method to write a junit, because the code seemed difficult
to read.

Perhaps at some stage we could re-visit these serialize() / fillFields()
methods of the org.apache.poi.hssf.record.Record hierarchy.  It's difficult to
keep track of byte array offsets while streaming record fields.  The JDK (with
DataInputStream / DataOutputStream) shows better examples of how to do this.