mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-03 08:51:30 -06:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01dee46561 |
+10
-1
@@ -470,6 +470,14 @@ impl Import {
|
||||
None => return Err(IoError::TooLarge("ODS row exceeds worksheet width".into())),
|
||||
};
|
||||
if kept {
|
||||
// Charge the text a row keeps before the row is done, so a row of many long cells is
|
||||
// refused as it grows; finish_row charges the row's repeats beyond the first.
|
||||
if let Value::Text(t) = &cell.value {
|
||||
self.text = self.text.saturating_add(u64::from(draft.repeat).saturating_mul(t.len() as u64));
|
||||
if self.text > MAX_TEXT {
|
||||
return Err(IoError::TooLarge("ODS expands beyond the import limit (64 MiB of text)".into()));
|
||||
}
|
||||
}
|
||||
row.cells.push(RepeatedCell { col: row.col, repeat: draft.repeat, width, height, cell });
|
||||
}
|
||||
row.col = end;
|
||||
@@ -537,7 +545,8 @@ impl Import {
|
||||
if !entry.cell.is_blank() {
|
||||
self.cells = self.cells.saturating_add(count);
|
||||
if let Value::Text(t) = &entry.cell.value {
|
||||
self.text = self.text.saturating_add(count.saturating_mul(t.len() as u64));
|
||||
let repeats = count.saturating_sub(u64::from(entry.repeat));
|
||||
self.text = self.text.saturating_add(repeats.saturating_mul(t.len() as u64));
|
||||
}
|
||||
}
|
||||
let merged = entry.width > 1 || entry.height > 1;
|
||||
|
||||
@@ -200,6 +200,18 @@ fn ods_expansion_bounds_stop_small_repeat_bombs() {
|
||||
"x".repeat(1024)
|
||||
);
|
||||
assert!(matches!(read_ods(&ods(&text)), Err(IoError::TooLarge(_))));
|
||||
// One row of cells each just under the 1 MiB cell limit, past 64 MiB in all: refused while
|
||||
// the row is read, before it holds them all. The row's end is never reached.
|
||||
let long = format!(r#"<table:table-cell office:value-type="string" office:string-value="{}"/>"#, "x".repeat(1024 * 1024 - 1));
|
||||
let cells = ods(&format!(r#"<table:table table:name="Data"><table:table-row>{}"#, long.repeat(65)));
|
||||
assert!(matches!(read_ods(&cells), Err(IoError::TooLarge(_))));
|
||||
// A row repeated once more than its cells' text allows is refused too, and one that fits reads.
|
||||
let cell = format!(r#"<table:table-cell office:value-type="string" office:string-value="{}"/>"#, "y".repeat(1024));
|
||||
let rows = |n: u32| {
|
||||
ods(&format!(r#"<table:table table:name="Data"><table:table-row table:number-rows-repeated="{n}">{cell}</table:table-row></table:table>"#))
|
||||
};
|
||||
assert!(read_ods(&rows(65_536)).is_ok());
|
||||
assert!(matches!(read_ods(&rows(65_537)), Err(IoError::TooLarge(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user