mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-27 04:06:52 -06:00
xlsx: warn when hyperlinks past the 10,000-cell cap are dropped on read (#513)
This commit is contained in:
@@ -104,7 +104,7 @@ pub fn read_sheet(cx: &mut Ctx<'_>, part: &str, name: &str) -> Result<Sheet, IoE
|
||||
}
|
||||
}
|
||||
}
|
||||
"hyperlinks" => read_hyperlinks(e, &rels, &mut sheet),
|
||||
"hyperlinks" => read_hyperlinks(cx, name, e, &rels, &mut sheet),
|
||||
"autoFilter" => sheet.autofilter = read_autofilter(cx, e),
|
||||
"printOptions" => {
|
||||
sheet.print.gridlines = e.flag("gridLines", false);
|
||||
@@ -709,7 +709,7 @@ fn read_validation(v: &El) -> Option<Validation> {
|
||||
})
|
||||
}
|
||||
|
||||
fn read_hyperlinks(e: &El, rels: &[Rel], sheet: &mut Sheet) {
|
||||
fn read_hyperlinks(cx: &mut Ctx<'_>, name: &str, e: &El, rels: &[Rel], sheet: &mut Sheet) {
|
||||
let mut cells = 0u64;
|
||||
for h in e.kids("hyperlink") {
|
||||
let Some(range) = h.attr("ref").and_then(RangeRef::parse) else { continue };
|
||||
@@ -727,6 +727,7 @@ fn read_hyperlinks(e: &El, rels: &[Rel], sheet: &mut Sheet) {
|
||||
let link = Hyperlink { target, tooltip: h.attr("tooltip").map(str::to_string) };
|
||||
for c in range.iter() {
|
||||
if cells >= MAX_HYPERLINK_CELLS {
|
||||
cx.warn(format!("sheet \"{name}\": hyperlinks past the first {MAX_HYPERLINK_CELLS} cells were dropped"));
|
||||
return;
|
||||
}
|
||||
cells += 1;
|
||||
|
||||
@@ -193,3 +193,19 @@ fn hostile_protected_ranges_stay_locked() {
|
||||
assert!(!matches!(h.verify("password"), Ok(true)), "{}", r.title);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hyperlinks_past_the_cell_cap_are_reported() {
|
||||
// A styles part, so the only possible warning is the hyperlink one.
|
||||
let parts = [("xl/styles.xml", r#"<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"/>"#)];
|
||||
let rels = r#"<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>"#;
|
||||
let body = r#"<sheetData/><hyperlinks><hyperlink ref="A1:A12000" location="x"/></hyperlinks>"#;
|
||||
let (wb, rep) = read_xlsx(&minimal(body, &parts, rels, "")).unwrap();
|
||||
assert_eq!(wb.sheet(0).unwrap().hyperlinks.len(), 10_000);
|
||||
assert!(rep.warnings.iter().any(|w| w.contains("hyperlinks past the first 10000 cells were dropped")), "{:?}", rep.warnings);
|
||||
// A small list reads in full with no warning.
|
||||
let body = r#"<sheetData/><hyperlinks><hyperlink ref="A1:A3" location="x"/></hyperlinks>"#;
|
||||
let (wb, rep) = read_xlsx(&minimal(body, &parts, rels, "")).unwrap();
|
||||
assert_eq!(wb.sheet(0).unwrap().hyperlinks.len(), 3);
|
||||
assert!(rep.warnings.is_empty(), "{:?}", rep.warnings);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user