A workbook GridCraft created had no <fileVersion> in workbook.xml; it now
names GridCraft, and keeps it on later saves.
A workbook read from an Excel file still keeps its <fileVersion> as it was,
appName="xl" included. Observed in Excel 16.114: with the calcFeatures
extension present, Excel uses the saved cell values only when appName is
"xl". appName="gridcraft", "Calc" or no appName makes it recalculate
everything on open, which brings back #799 (lookups into closed workbooks
open as #CALC!). The application that last saved the file is recorded in
docProps/app.xml <Application>GridCraft</Application>, which GridCraft
already writes on every save and which Excel's recalculation ignores.
A hostile file could abort any process that opens it: a cell formula of a
million `%` (`1%%%…`) or a 200,000-term sum parsed into trees deep enough to
overflow the stack when printed, saved, evaluated or dropped, even in release
builds. Postfix operators (`%`, invoking a result) built their nesting in a
loop that the 256-level limit did not see.
- `parse` refuses formula text longer than Excel's 8,192 characters
(`MAX_FORMULA_LEN`, counted in characters, the leading `=` excluded). This
also bounds the depth of the left-deep trees long operator chains build.
- Each postfix `%` and each call of a result counts towards the nesting limit.
- A file's formula that is refused keeps its text and cached value, as other
unparsable formulas do.
Regression tests: formula (small-stack thread: long `%`, invoke and operator
chains are errors; the limit counts characters, not bytes) and xlsx
(`hostile_formula_text_does_not_overflow_the_stack`: open, save and drop a
workbook with such formulas and a defined name on a 1 MiB stack). Both abort
with a stack overflow without the fix.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Brings the branch up to upstream's main (180 more commits). One conflict,
and one thing the merge needed that was no conflict:
- docs/ui-parity.md: every line of both sides is kept, as upstream's own
merges keep them (its heading has three lines now); this change's
heading line and history row come first.
- crates/ui-egui/src/i18n/pt.rs: upstream's Portuguese catalog gained a
"Yesterday" of its own, with the same word ("Ontem"). The one this change
added is left out: a second arm for the same text is unreachable.
Gate: all eight steps, 1548 tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- restore closing braces the line-level merges of side-by-side tests dropped
- new ChartData literals carry the palette field
- the filter-menu shortcut passes the row with the column
- #688's tab tests account for #851's All Sheets button
- Serbian margins for the ruler-margin labels
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>