- automate.trustScripts: only a missing `trusted` defaults to true; a
non-boolean value is an error and leaves the workbook untrusted.
- The refusal message points at Trust Scripts in View > Macros (Alt+F8)
and at automate.trustScripts.
- Catalog row for automate.trustScripts; parity checklist regenerated.
- Script steps run inside an io::ScriptSandbox (thread-local) so
read_file/write_file refuse whatever the parameter is called, and a
step that raises OpenUrl is dropped and stops the script. The id/param
deny list stays as the up-front refusal.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A workbook opened with GridCraft scripts (`_sc_scripts`) starts untrusted:
automate.runScript refuses them until the user trusts the workbook for the
session (Macros dialog > Trust Scripts, i.e. automate.trustScripts) or the
caller passes `trusted: true` for that one run. Workbooks without scripts,
and scripts written in the session, are unaffected.
Whatever the trust, a script whose steps reach outside the workbook
(file.*, link.*, or any `path` param: Get Data, From Text/CSV, Insert
Picture) is refused before any step runs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Clipboard HTML is read only as far as the pasted text's shape (clamped
to the sheet) and at most 1,000,000 cells; colspan/rowspan are clamped
to the sheet extent before expanding, and rowspan now keeps later rows
in their columns.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
zip2 (binary operators, TEXT), zip3 (array IF) and MAP now compute the
broadcast cell count with checked multiplication and return #NUM! when it
exceeds MAX_CELLS, instead of allocating (abort) or wrapping on wasm32.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Parenthesised negatives were parsed by recursing once per level, so runtime
text such as REPT("(",32767)&"1"&REPT(")",32767) overflowed the stack. Strip
the parentheses in a loop, toggling the sign per level; results are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every area, array and value of one SUBTOTAL/AGGREGATE call is charged against MAX_CELLS before any cell is read; past it the call returns #NUM!. A value stored in XFD1048576 no longer makes SUBTOTAL(9,A:XFD) read ~17 billion cells into a vector.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LINEST, LOGEST, TREND and GROWTH built k x k normal-equation matrices
(plus two copies in sym_inverse, O(k^3)) with k taken straight from the
known_xs shape, so one formula could allocate gigabytes and abort on open.
More than 255 predictors is now #VALUE!, and more than 1e9 rows x k^2
multiply-adds is #NUM!, both checked before any allocation.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Excel counts TRUE/FALSE and error values as strings in a cache field's
<sharedItems>. GridCraft wrote containsString="0" (and counted booleans and
errors as separate kinds for containsMixedTypes) for such columns, which made
the file unopenable in Excel, even when the column wasn't used in the pivot.
Add Stats::strings() (text, booleans, errors) and use it for
containsSemiMixedTypes, containsString and containsMixedTypes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>