#[path = "fixtures/mod.rs"]
mod fixtures;
use fixtures::security;
use std::io::Cursor;
use xlsxparser::{
parse_workbook_reader, parse_workbook_reader_with_limits, to_json_string, Error, SizeLimits,
};
#[test]
fn sparse_merge_bounding_box_does_not_amplify_json_generation_cost() {
let workbook = parse_workbook_reader(Cursor::new(
security::sparse_merge_bounding_box_amplification(),
))
.unwrap();
assert_eq!(workbook.sheets()[0].iter_cells().count(), 320_000);
let json = to_json_string(&workbook).unwrap();
assert!(json.contains("\"maxRow\":1048576"));
}
#[test]
fn zip_bomb_is_capped_before_full_decompression() {
let tiny_cap = SizeLimits {
max_entry_size: 1_000_000,
max_total_size: SizeLimits::default().max_total_size,
};
let err =
parse_workbook_reader_with_limits(Cursor::new(security::zip_bomb()), tiny_cap).unwrap_err();
assert!(
matches!(err, Error::ZipBombDetected { .. }),
"expected Error::ZipBombDetected, got {err:?}"
);
}
#[test]
fn zip_slip_entry_name_rejects_the_whole_archive() {
let err = parse_workbook_reader(Cursor::new(security::zip_slip())).unwrap_err();
assert!(
matches!(err, Error::ZipSlipDetected { .. }),
"expected Error::ZipSlipDetected, got {err:?}"
);
}
#[test]
fn xxe_doctype_is_rejected_without_entity_expansion() {
let err = parse_workbook_reader(Cursor::new(security::xxe_attack())).unwrap_err();
assert!(
matches!(err, Error::DoctypeRejected { .. }),
"expected Error::DoctypeRejected, got {err:?}"
);
}