Skip to content

[patch] Anchor IBAN, UUID and ULID patterns at the true end, and strip all whitespace from an IBAN - #405

Merged
matt-edmondson merged 2 commits into
mainfrom
fix/311-anchor-identifiers-at-end
Oct 9, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
fix/311-anchor-identifiers-at-end

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #311

What was wrong

  • In .NET, $ without RegexOptions.Multiline also matches just before a final \n. [IsIban], [IsUuid] and [IsUlid] all ended their patterns with $, so a value with a trailing newline passed the structural check.
  • Iban.MakeCanonical stripped only ' ', so a newline reached PassesMod97 and was scored as a letter ('\n' - 'A' + 10). As a result, GB67WEST12345698765432\n, which has the wrong check digits, validated, while the valid GB82WEST12345698765432\n was rejected as "mod-97 checksum failed".

Change (Semantics.Strings.Identifiers)

  • IsIbanAttribute, IsUuidAttribute, IsUlidAttribute: patterns now end in \z instead of $.
  • Iban.MakeCanonical strips every char.IsWhiteSpace character (spaces, tabs, CR/LF, NBSP) and uppercases. That's what the type's summary and the identifiers spec already said it did.
  • I grepped the other Semantics.* projects for $-anchored validation patterns, as the triage suggested. These three were the only ones.

Tests

  • IbanTests.Create_InvalidChecksumWithTrailingNewline_Throws: GB67…\n and GB67…\r\n are rejected.
  • IbanTests.Create_ValidIbanWithWhitespace_StripsItAndValidates: trailing \n and \t, a leading tab with trailing CRLF, the spaced form plus \n, and NBSP separators all canonicalize to GB82WEST12345698765432.
  • UuidTests / UlidTests: a private type that applies [IsUuid] / [IsUlid] without trimming rejects a trailing \n, and still accepts the bare value.
  • With the fix reverted, 8 of these cases fail. The \r\n rows already passed and are kept as guards. With the fix, the full Semantics.Test suite passes: 1491 passed, 0 failed, 8 skipped. Semantics.Strings.Identifiers builds for every target framework with no warnings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Co2rZq6e7TjwF2FMUzNoXu


Generated by Claude Code

…p all whitespace from an IBAN

In .NET, $ also matches before a final "\n", so [IsIban], [IsUuid] and
[IsUlid] accepted a value with a trailing newline. Iban only stripped
spaces, so the newline reached the mod-97 check as if it were a letter:
"GB67WEST12345698765432\n" (wrong check digits) validated, and the valid
"GB82WEST12345698765432\n" was rejected as a checksum failure. The patterns
now end in \z, and Iban strips every whitespace character, as its
documentation says it does.

Fixes #311

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Co2rZq6e7TjwF2FMUzNoXu
Comment thread Semantics.Strings.Identifiers/Iban.cs Fixed
@sonarqubecloud

sonarqubecloud Bot commented Oct 8, 2026

Copy link
Copy Markdown

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.

Iban accepts an invalid IBAN ending in "\n" and rejects a valid one with the same newline (regex $ matches before a trailing newline)

2 participants