Skip to content

Color.FromHex accepts "#+F+F+F" as #0F0F0F and throws FormatException (not ArgumentException) for non-hex characters #313

Description

@matt-edmondson

What's wrong

Semantics.Color/Color.Conversions.cs FromHex (L49-L70) checks only the string's length, then parses each channel with ParseByte (L99-L100): Convert.ToByte(hex.Substring(index, 2), 16). Convert.ToByte(string, 16) has two quirks that leak through:

  • A leading + is accepted, so Color.FromHex("#+F+F+F").ToHex() returns "#0F0F0F" and invalid input is accepted without complaint. The same applies to "+F" inside any 6- or 8-digit string.
  • A non-hex character throws FormatException, so FromHex("#GGGGGG") and FromHex("#0x0x0x") both throw it. FromHex("#-1-1-1") throws ArgumentException instead. The exception type therefore depends on which bad character appears.

The XML docs for FromHex list only ArgumentNullException and ArgumentException, and CLAUDE.md says to throw ArgumentException for validation failures, not FormatException. A caller that validates user or theme input with catch (ArgumentException) crashes on #GGGGGG and silently accepts #+F+F+F.

All of these were reproduced by compiling Semantics.Color into a scratch console app.

Suggested fix

  • After length normalisation, check that every character is [0-9A-Fa-f], and throw ArgumentException(..., nameof(hex)) if one is not.
  • Parse each channel with byte.Parse(span, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture), which rejects signs.
  • Add tests: #+F+F+F, #GGGGGG, #0x0x0x and #-1-1-1 all throw ArgumentException, and valid 3/6/8-digit inputs in either case still round-trip.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions