Skip to content

fix(api): reject non-finite chart values#187

Merged
DemchaAV merged 3 commits into
developfrom
fix/new-primitive-fail-loud
Jun 14, 2026
Merged

fix(api): reject non-finite chart values#187
DemchaAV merged 3 commits into
developfrom
fix/new-primitive-fail-loud

Conversation

@DemchaAV

@DemchaAV DemchaAV commented Jun 14, 2026

Copy link
Copy Markdown
Owner

Why

ChartData.Series accepted NaN/Infinity. A non-finite value poisoned NiceScale axis derivation (NaN != NaN defeats the degenerate-range guard) and only surfaced as a misleading "height must be finite: NaN" thrown deep inside ChartPrimitive — far from the bad data. (Senior-review audit follow-up; caught before 1.8.0 ships.)

What

  • ChartData.Series rejects non-finite values at construction, naming the series and offending index; null stays a valid gap. Verified: the null guard runs before auto-unboxing (no NPE), and the check sits before ChartData's ragged-length check so a NaN is reported as the NaN error.
  • New ChartDataTest (5 cases: null-gap allowed, NaN rejected naming the index, ±∞ rejected, finite builds, ragged rejected).

Review note

This PR originally also tightened PathNode to require a drawing segment. Independent review found that change was a false positive on the @Beta SVG-import path (SvgIcon.node() threw on a [MoveTo, Close] element that rendered harmlessly on develop). It was chasing a cosmetic message nit, so it was reverted — PathNode is byte-identical to develop. The proper stray-subpath fix (drop drawing-less layers in SvgIconReader) is deferred to the SVG-hardening lane.

Tests

Full suite 1357 green.

Lane: canonical (document.chart). Additive validation only.

DemchaAV added 2 commits June 14, 2026 13:11
Two authoring-time validation gaps on the new 1.8.0 primitives, both
caught before 1.8.0 ships:

- ChartData.Series accepted NaN/Infinity, which poisoned NiceScale axis
  derivation (NaN != NaN defeats the degenerate-range guard) and only
  surfaced as a misleading 'height must be finite: NaN' thrown deep in
  ChartPrimitive. Reject non-finite values in the Series constructor,
  naming the series and the offending index; null stays a valid gap.

- PathNode accepted a [MoveTo, Close] segment list (size 2, MoveTo-first)
  that renders an empty subpath, while its own error message promised a
  'drawing segment'. Require at least one LineTo/CubicTo after the MoveTo
  so the contract the message advertises is actually enforced.

Adds ChartDataTest (new) and a PathNodeTest case. Full suite green.
Independent review of #187 found the PathNode 'require a drawing segment'
guard is a false positive on the headline @beta SVG-import path:
SvgIcon.node() threw IllegalArgumentException for a visible-painted element
that lowers to [MoveTo, Close] (e.g. d="M12 12 Z"), which rendered
harmlessly on develop. Real exporters emit such stray subpaths, and the
guard was only chasing a cosmetic 'message overpromises' nit — not worth a
behavioural regression on a leaf primitive that the SVG reader feeds.

Revert PathNode + PathNodeTest to develop verbatim; the PR now carries only
the ChartData.Series non-finite rejection (correct and valuable). Also
tighten ChartDataTest's 'index 1' substring to 'index 1 must be finite' so
it cannot accidentally match 'index 10'. Full suite green (1357).

The cleaner fix for the stray-subpath case (drop drawing-less layers in
SvgIconReader, which also covers the pre-existing lone-MoveTo fragility)
belongs in the separate SVG-hardening lane, not here.
@DemchaAV DemchaAV changed the title fix(api): fail loud on non-finite chart values and empty paths fix(api): reject non-finite chart values Jun 14, 2026
@DemchaAV DemchaAV merged commit e93d0f5 into develop Jun 14, 2026
11 checks passed
@DemchaAV DemchaAV deleted the fix/new-primitive-fail-loud branch June 14, 2026 13:08
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.

1 participant