Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/xlsb/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,11 @@ impl<RS: Read + Seek> Xlsb<RS> {
}
}
0x0090 => break, // BrtEndBundleShs
_ => (),
_ => {
// Consume the body of any unmatched workbook-global record
// to avoid reading its trailing bytes in the next read.
let _ = iter.fill_buffer(&mut buf)?;
}
}
buf.clear();
}
Expand Down
Binary file added tests/issue_666_lost_sheets.xlsb
Binary file not shown.
Binary file added tests/issue_666_panic.xlsb
Binary file not shown.
21 changes: 21 additions & 0 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3550,6 +3550,27 @@ fn test_whitespace_trim_shared_strings() {
);
}

// An unmatched workbook-global record whose body is left unconsumed desyncs the
// BIFF12 record stream: the next `read_type()` misreads the record's size-varint
// bytes as the next record id. Both fixtures hold a single "Sheet1" worksheet
// preceded by such a record; without consuming its body the sheet is either lost
// or the reader panics. See issue #666.
#[test]
fn test_xlsb_unmatched_workbook_record_does_not_lose_sheet() {
// The unmatched record's body size varint starts with `0x90`, which the
// desynced reader misreads as `BrtEndBundleShs` and stops before any sheet.
let xlsb: Xlsb<_> = wb("issue_666_lost_sheets.xlsb");
assert_eq!(xlsb.sheet_names(), vec!["Sheet1".to_string()]);
}

#[test]
fn test_xlsb_unmatched_workbook_record_does_not_panic() {
// The unmatched record's body size varint starts with `0x9C`, which the
// desynced reader misreads as `BrtBundleSh` and decodes from an empty buffer.
let xlsb: Xlsb<_> = wb("issue_666_panic.xlsb");
assert_eq!(xlsb.sheet_names(), vec!["Sheet1".to_string()]);
}

#[test]
fn too_small_xls() {
let path = test_path("too_small.xls");
Expand Down
Loading