Skip to content

fix: handle unmatched optional capture groups in stateful lexer actions - #464

Open
Pastalikek65 wants to merge 1 commit into
alecthomas:masterfrom
Pastalikek65:fix-lexer-empty-capture-group
Open

fix: handle unmatched optional capture groups in stateful lexer actions#464
Pastalikek65 wants to merge 1 commit into
alecthomas:masterfrom
Pastalikek65:fix-lexer-empty-capture-group

Conversation

@Pastalikek65

Copy link
Copy Markdown
Contributor

When a stateful lexer rule has an optional capture group that does not match (e.g. [a-z]([a-z])? matching "a"), regexp.FindStringSubmatchIndex reports it with indices of -1. Building the groups passed to Actions sliced the input with those indices, panicking with slice bounds out of range.

The reported %x + y case from #324 is a real-world instance: the keyword/Ident design pushes a state on %, and the next rule's action (Pop) crashed on the unmatched capture group.

Changes:

  • lexer/stateful.go: unmatched capture groups are passed to actions as empty strings instead of panicking. Keeping the group position (rather than dropping it) also preserves the meaning of \n backreferences to later states — an unmatched group genuinely captures the empty string.
  • lexer/stateful_test.go: two new table cases — "UnmatchedOptionalCaptureGroup" (panics before this fix, per Panic when stateful lexer's non-Root rule has optional group but captures nothing #324) and "BackrefMatchesEmptyCaptureGroup" (exercises the parent-state group hand-off).

Verification: go test ./... (root + _examples) green; golangci-lint — no new issues.

Fixes #324.

When a rule has an optional capture group that does not match, regexp reports it with indices of -1. Building action groups from those indices panicked with a slice bounds error. Unmatched groups are now passed to actions as empty strings, which also prevents backreferences from shifting to the wrong group (issue alecthomas#324).

Fixes alecthomas#324.
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.

Panic when stateful lexer's non-Root rule has optional group but captures nothing

1 participant