fix(xlsx): read .xls files whose Workbook stream ends in padding
What
partition_xlsx() now reads .xls files whose Workbook stream ends in a few bytes of padding, such as many files written by xlwt. Before, these raised struct.error: unpack requires a buffer of 4 bytes from the msoffcrypto encryption check. Closes #4544.
xlwt workbook, 3 rows (example-docs/xlwt-padded-workbook.xls)
Before: struct.error: unpack requires a buffer of 4 bytes
After: [Table("Fruit Count Apple 3 Pear 7")]
Why
msoffcrypto's is_encrypted() scans an XLS Workbook stream as 4-byte record headers, looking for a FilePass record. xlwt pads the stream with zeros to a 4096-byte boundary, and when fewer than 4 bytes of padding are left, the scan raises (nolze/msoffcrypto-tool#83). A struct.error from that check is now read as "not encrypted". This does not let a password-protected .xls through: its FilePass record directly follows the BOF record, so the scan finds it before any padding. msoffcrypto's rc4cryptoapi_password.xls and xor_password_123456789012345.xls samples are still rejected with "XLSX file is password protected.", and its plain.xls sample still partitions.
Validation
test_partition_xlsx_reads_xls_whose_workbook_stream_ends_in_paddingpartitions a 5.6 KBxlwtfixture. It fails onmainwith thestruct.errorand passes here.test_unstructured/partition/test_xlsx.py: 108 passed.ruff checkandruff format --checkpass on the changed files.- CHANGELOG entry under 0.27.27, with the version bumped. #4543 also bumps to 0.27.27; I'll rebase whichever merges second.