feat(dummies): validate named group names and reject balancing groups - #271
Merged
Conversation
SkipGroupName scanned a named-group name to its terminator without
validating it, so two well-formed .NET constructs slipped through as
ordinary named groups:
- a balancing group '(?<-name>…)' / '(?<name1-name2>…)' is non-regular
(it pops the capture stack, the backreference family). Lowering it to
a plain named group mis-generated: '(?<a>y)?(?<-a>x)' has language
{"yx"}, yet the generator could emit "x" — the exact silently
non-matching value ADR-0025 forbids;
- an invalid group name (a space, a dot, a bad numeric form) was
accepted where the real engine rejects it.
Validate the captured name at the call site: a '-' is refused as an
unsupported balancing group, including when its target is undefined
(where .NET reports a malformed pattern instead — telling the two apart
would need a capture table the generator deliberately does not keep, so
the divergence is only in the error kind, both reject and neither
mis-generates); a name opening with a digit must be a positive group
number with no leading zero ('1', '10'; not '0', '01', '1a'); any other
name must be word characters. Numbered and ordinary named groups keep
parsing and generating unchanged, in both the '(?<…>)' and '(?'…')'
syntaxes.
Refs: #209
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjjDWNEx4riWGjx19FmPN9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The regex parser now validates named group names as the real .NET engine would, rejecting invalid names and balancing groups that manipulate the capture stack. This ensures that patterns accepted by Dummies stay aligned with patterns accepted by .NET, preventing silent mis-generation of non-regular constructs.
Type of change
Changes
Named group name validation: Added
ValidateGroupName()method that checks group names according to .NET rules:(?<name1-name2>…)/(?<-name>…)) as unsupported, since they manipulate the capture stack (non-regular)ArgumentExceptionfor malformed names, mirroring the real engineUnsupportedRegexExceptionfor balancing groups, even when the target group is undefined (divergence from .NET's malformed-pattern verdict is accepted since the generator lacks a capture-group table)Updated
SkipGroupName()signature: Now accepts apositionparameter to enable proper error reporting, and callsValidateGroupName()after parsing the nameUpdated documentation:
RegexParserclass documentation now mentions that group names are validatedUnsupportedRegexExceptiondocumentation updated to list balancing groups as a refused constructValidateGroupName()explaining the validation rules and the deliberate divergence from .NET on undefined balancing-group targetsAdded unit tests:
AnyPatternTests.AnyPatternTests(): Added valid patterns with explicitly-numbered groups and named groups containing digitsBalancingGroupsAreRefused(): Tests that balancing groups are rejected in both syntaxes and whether the target is defined or notInvalidGroupNamesAreRejected(): Tests that invalid names (leading zeros, non-word characters, reserved group 0) are rejected as malformedTesting
dotnet build FirstClassErrors.slndotnet test FirstClassErrors.slnArchitecture decisions
Related issues
https://claude.ai/code/session_01RjjDWNEx4riWGjx19FmPN9