Found while testing crates/engine/src/cmd/data.rs:992 (split_delimited, used by text_to_columns)
Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
* calc: linear dependency extraction for range-operator chains (#2183)
precedents() handled a range operator with non-reference operands by recursing into both operands and then letting Expr::walk descend into them again, so a left-associative chain of k operands cost 2^k (a 60-operand INDEX(...):INDEX(...) chain would hang on open). It is now a hand-written collector that visits every node once, growing the per-sheet bounding boxes of the enclosing range operator as it goes. Past a depth (4096) or node (1,000,000) bound it marks the formula dynamic (always recalculated) instead of recursing further.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* calc: drop wall-clock timing from precedents tests (clippy)
std::time::Instant::now is a disallowed method (clippy.toml: traps on wasm).
The regression test only needs to finish; the old 2^k walk would never return.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* calc: bound precedents to 100 ms and box plain-reference range chains (#2183)
- range_operator_chain_precedents_are_linear times the direct precedents
call against the 100 ms bound in the issue.
- A Range node with two plain Ref operands (A1:B2:C3, which the parser
can't fold) now collects its bounding box like any other range node, so
an edit to C1 recalculates.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* M0: reject negative fractional GCD and LCM arguments
Validate the original input before truncation. Add scalar and range regressions, including signed zero, positive fractions and zero-first LCM validation.
* M0: document negative-fraction GCD and LCM regression
Record tested edge-case behavior and update the parity revision history. Function counts and readiness estimates remain unchanged.
* M0: preserve GCD and LCM regression after math test extraction
Move the original negative-fraction regression into the existing extracted math tests. Scalar and range cases, zero-first validation, signed zero and positive truncation coverage are unchanged.
ACCRINTM returned #NUM! whenever issue >= settlement. Excel rejects only
an issue date after settlement: when the two dates are equal after
truncation to whole days (including distinct times on the same day) it
returns 0 in every basis and both date systems. Relax the guard to
issue > settle; zero rate, zero par and an invalid basis stay #NUM!.
craft-cfb refuses a header without the 0xFFFE mark at offset 28
([MS-CFB] 2.2), so craft-xls's sniff called the fixture LegacyBinary.
The old hand-written parser never read that field, which is why the test
only broke with the switch. The fixture is a real workbook otherwise:
sniff now says Xls and read_xls parses it.
craft-cfb refuses a header without the 0xFFFE mark at offset 28
([MS-CFB] 2.2), so craft-xls's sniff called the fixture LegacyBinary.
The old hand-written parser never read that field, which is why the test
only broke with the switch. The fixture is a real workbook otherwise:
sniff now says Xls and read_xls parses it.