https://bz.apache.org/bugzilla/show_bug.cgi?id=70292
Bug ID: 70292
Summary: [PATCH] HSSF: FileSharingRecord ignores fHighByte of
user name - LeftoverDataException for write-protected
.xls with non-ASCII user name
Product: POI
Version: 6.0.0-FINAL
Hardware: All
OS: All
Status: NEW
Severity: normal
Priority: P2
Component: HSSF
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
Created attachment 40239
--> https://bz.apache.org/bugzilla/attachment.cgi?id=40239&action=edit
xls password : test
Opening a write-protected (password to modify / "read-only recommended") .xls
file
fails if the Excel user name stored in the FILESHARING record contains
non-ASCII
characters (e.g. Korean, Japanese, Chinese user names).
Steps to reproduce:
1. In Excel, set a non-ASCII user name (File > Options > General > User name),
e.g. "홍길동".
2. Save an .xls (Excel 97-2003) with "Password to modify" set
(no "Password to open" is required to reproduce).
3. new HSSFWorkbook(new FileInputStream("sample.xls"));
The attached file FileSharingRecord-unicode-username.xls reproduces this.
Actual result:
org.apache.poi.hssf.record.RecordInputStream$LeftoverDataException:
Initialisation of
record 0x5B(FileSharingRecord) left 3 bytes remaining still to be read.
at
org.apache.poi.hssf.record.RecordInputStream.hasNextRecord(RecordInputStream.java:176)
at
org.apache.poi.hssf.record.RecordFactoryInputStream.nextRecord(RecordFactoryInputStream.java:235)
at
org.apache.poi.hssf.record.RecordFactory.createRecords(RecordFactory.java:187)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:378)
...
Expected result:
The workbook opens normally (Excel opens the file without problems).
Analysis:
According to MS-XLS 2.4.117 FileSharing, stUNUsername is an XLUnicodeString
(cch: 2 bytes, fHighByte: 1 byte, rgb). If bit 0 of fHighByte is 1, the
characters
are stored as UTF-16LE (2 bytes per character).
FileSharingRecord(RecordInputStream) reads fHighByte into
field_3_username_unicode_options but ignores it and always calls
readCompressedUnicode(nameLen). For a 3-character Korean user name the record
is
13 bytes (2+2+2+1+6), POI consumes only 10 bytes, so 3 bytes are left over.
The existing TODO comment in the constructor notes that the junit examples only
have zero-length user names.
serialize()/getDataSize() have the same assumption (always 8-bit), so a
non-ASCII
user name set via HSSFWorkbook.writeProtectWorkbook() is written incorrectly.
Affected versions: 5.5.1 and 6.0.0 (the code is unchanged in trunk).
This is independent of encryption: it also happens with "password to modify"
only.
Patch:
The attached patch (against REL_6_0_0) checks bit 0 of fHighByte and uses
readUnicodeLEString() for 16-bit names, writes 16-bit names in serialize()/
getDataSize() when the user name has multibyte characters, and consumes a
trailing fHighByte for empty user names. It adds TestFileSharingRecord covering
8-bit and UTF-16LE user names (read + round-trip).
We have verified the fix with real Excel files saved with a Korean user name.
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]