Skip to content

xlstream-eval: bound VLOOKUP and INDEX col index to range width#186

Merged
cilladev merged 2 commits into
mainfrom
fix/vlookup-range-bounds
Jun 5, 2026
Merged

xlstream-eval: bound VLOOKUP and INDEX col index to range width#186
cilladev merged 2 commits into
mainfrom
fix/vlookup-range-bounds

Conversation

@cilladev

@cilladev cilladev commented Jun 4, 2026

Copy link
Copy Markdown
Owner

Fixes: #143

Problem

builtin_vlookup and builtin_index extracted start_col from the table/range RangeRef but ignored end_col. A col_index/col_num past the range's last column read neighboring data from the loaded lookup sheet instead of returning #REF!. Example: =VLOOKUP(1, Lookup!A:A, 2, FALSE) returned column B's value instead of #REF!.

Fix

Both functions now capture end_col, compute the declared range width (end_col - start_col + 1), and return #REF! when the column index exceeds it — matching Excel. The check is skipped when end_col is None (whole-row refs already fail the start_col: Some(..) guard).

Changes

  • crates/xlstream-eval/src/builtins/lookup.rs: capture end_col in VLOOKUP and INDEX destructures; add a width bound check returning #REF! for out-of-range column indices.
  • Unit tests: vlookup_col_index_past_range_returns_ref, vlookup_col_index_at_range_width_ok, index_col_past_range_returns_ref.
  • Conformance fixture issue-143-lookup-range-bounds.xlsx (Excel-populated): 38 formula cells across 5 rows covering valid lookups, #REF! (col past 1-col and 3-col ranges, both functions), plus #N/A (miss) and #VALUE! (col_index 0) singletons.

Scope note

The fix targets column bounds, as the issue describes. INDEX with a row past the loaded data of a whole-column range (INDEX(A:C, 100, 1)) is a separate concern: Excel treats it as in-range-empty (0) while xlstream returns #REF! (it only loads actual data rows). That deviation is pre-existing and intentional (see the existing index_out_of_bounds unit test), so it is out of scope here and excluded from the fixture.

Test plan

  • Regression unit tests added and pass
  • Conformance fixture created (Excel-populated) and passes
  • cargo test -p xlstream-eval passes (2265 lib + 137 doc, no regressions)
  • make check passes

Closes #143

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.

Benchmark suite Current: bb31644 Previous: c90c6b8 Ratio
arithmetic/concat 258 ns/iter (± 13) 210 ns/iter (± 2) 1.23

This comment was automatically generated by workflow using github-action-benchmark.

@cilladev cilladev merged commit 0bded9d into main Jun 5, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

VLOOKUP and INDEX read past declared range boundaries

1 participant