Skip to content

Reject non-numeric input in Length.TryParse - #195

Merged
TylerBrinks merged 1 commit into
TylerBrinks:masterfrom
jhaygood86:bugfix/length-zero-requires-parsed-number
Jul 23, 2026
Merged

Reject non-numeric input in Length.TryParse#195
TylerBrinks merged 1 commit into
TylerBrinks:masterfrom
jhaygood86:bugfix/length-zero-requires-parsed-number

Conversation

@jhaygood86

Copy link
Copy Markdown
Contributor

Problem

Length.TryParse reports success for input that is not a length at all:

Length.TryParse("auto", out var r);   // true, r == 0px
Length.TryParse("red", out var r);    // true, r == 0px
Length.TryParse("", out var r);       // true, r == 0px
Length.TryParse("garbage", out var r) // true, r == 0px

The zero fallback exists for a good reason — CSS Values 3 §5.2 allows a zero length to omit its unit — but it keys only on the value:

var unitString = s.StylesheetUnit(out var value);
var unit = GetUnit(unitString);

if (unit != Unit.None) { result = new Length(value, unit); return true; }

if (value == 0f) { result = Zero; return true; }   // <-- also matches "auto", "red", ""

StringExtensions.StylesheetUnit sets result = default (0) both when it parses a unitless zero and when it can't find a number at all, so the two are indistinguishable by value alone.

Fix

They are distinguishable by the returned unit string — empty for a plain number, null when nothing could be tokenized — so check that too.

Angle, Frequency and Resolution have no equivalent fallback (they require a recognised unit), so this is specific to Length.

Tests

New LengthTests.cs, 19 theory cases:

  • values with units, including 0px and negatives
  • unitless zero in its accepted forms — 0, 0.0, -0
  • non-length input that must now be rejected — "", auto, inherit, red, px, %, garbage
  • a non-zero number without a unit (5, -2.5) and an unrecognised unit (10foo)

7 fail on master. The full suite (1263 existing tests) stays green, and all seven target frameworks build with no new warnings.

Length.TryParse falls back to returning Zero whenever the parsed value
is 0, to honour "a zero length may omit its unit". But
StringExtensions.StylesheetUnit sets its out parameter to 0 both when it
parses a unitless zero and when it fails to find a number at all, so the
fallback also fired for input that is not a length:

  Length.TryParse("auto", out var r)      // true, r == 0px
  Length.TryParse("red", out var r)       // true, r == 0px
  Length.TryParse("", out var r)          // true, r == 0px

The two cases are distinguishable by the returned unit string: empty for
a plain number, null when nothing could be tokenized. Check it as well
as the value.

Angle, Frequency and Resolution have no equivalent fallback - they
require a recognised unit - so this is specific to Length.
@jhaygood86
jhaygood86 marked this pull request as ready for review July 22, 2026 21:27
@jhaygood86
jhaygood86 marked this pull request as draft July 22, 2026 21:40
@jhaygood86
jhaygood86 marked this pull request as ready for review July 22, 2026 21:44
@TylerBrinks
TylerBrinks merged commit cb2d4db into TylerBrinks:master Jul 23, 2026
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.

2 participants