Skip to content

[patch] Reject non-hex characters in Color.FromHex with ArgumentException - #399

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/313-color-fromhex-validation
Oct 10, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/313-color-fromhex-validation

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #313

What was wrong

Color.FromHex checked only the string's length, then parsed each channel with Convert.ToByte(s, 16). That call has two quirks:

  • It accepts a leading +, so #+F+F+F was silently accepted as #0F0F0F.
  • It throws FormatException for most other bad characters (#GGGGGG, #0x0x0x) and ArgumentException for -. The exception type depended on which bad character showed up, and the docs promise only ArgumentException.

Change (Semantics.Color/Color.Conversions.cs)

  • After the length check (and 3-digit expansion), every character must be 0-9, A-F or a-f. Anything else throws ArgumentException(..., nameof(hex)), which names the bad character.
  • Convert.ToByte now only ever sees hex digits, so it can no longer accept a sign or throw FormatException. I kept it rather than switching to byte.Parse(ReadOnlySpan<char>, …) because that overload isn't available on the netstandard2.0 target.
  • Updated the <exception> doc to cover non-hex characters.

Tests (HexConversionTests)

  • FromHex_NonHexCharacter_ThrowsArgumentException: #+F+F+F, +F+F+F, #00+F00, #GGGGGG, #0x0x0x, #-1-1-1, #12345G, #FFFFFF+F, #F F, and #G00 all throw exactly ArgumentException.
  • FromHex_ValidDigitsInEitherCase_RoundTrip: valid 3, 6 and 8-digit inputs in lower and upper case, with and without #, still round-trip.

With the fix reverted, 9 of these cases fail. With the fix, the full Semantics.Test suite passes: 1495 passed, 0 failed, 8 skipped. Semantics.Color builds for every target framework.

🤖 Generated with Claude Code

https://claude.ai/code/session_019RYN9jT6szUiySkywFKCA1


Generated by Claude Code

…tion

Fixes #313

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019RYN9jT6szUiySkywFKCA1
@sonarqubecloud

sonarqubecloud Bot commented Oct 8, 2026

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit e886a57 into main Oct 10, 2026
14 of 15 checks passed
@matt-edmondson
matt-edmondson deleted the fix/313-color-fromhex-validation branch October 10, 2026 12:17
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.

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

2 participants