Skip to content

Commit

Permalink
Fix missing flag from regex literal in corner case
Browse files Browse the repository at this point in the history
In the specific corner case where a regex contains a flag but is not
followed by any symbols, the ast.RegExpLiteral.Literal value would drop
(part of) that flag.

This happens because the p.next() call during the parsing of the flag
wouldn't actually advance the p.chrOffset, and thus endOffset would be
erroneously adjusted.

The fix is just to use the current p.chrOffset and then call p.next()
afterwards.
  • Loading branch information
psve committed Jul 8, 2024
1 parent d4edd51 commit f2e254a
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
2 changes: 1 addition & 1 deletion parser/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ func (p *parser) parseRegExpLiteral() *ast.RegExpLiteral {
flags := ""
if p.token == token.IDENTIFIER { // gim
flags = p.literal
endOffset = p.chrOffset
p.next()
endOffset = p.chrOffset - 1
}

var value string
Expand Down
26 changes: 26 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,32 @@ func Test_parseNumberLiteral(t *testing.T) {
})
}

func Test_praseRegExpLiteral(t *testing.T) {
tt(t, func() {
test := func(input, literal, pattern, flags string) {
parser := newParser("", input, 1, nil)
program, err := parser.parse()
is(err, nil)

regex := program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.RegExpLiteral)
is(regex.Literal, literal)
is(regex.Pattern, pattern)
is(regex.Flags, flags)
}

test("/abc/", "/abc/", "abc", "")
test("/abc/gim", "/abc/gim", "abc", "gim")
test("/abc/ ", "/abc/", "abc", "")
test("/abc/gim ", "/abc/gim", "abc", "gim")
test("/abc/;", "/abc/", "abc", "")
test("/abc/gim;", "/abc/gim", "abc", "gim")
test("/abc/\n", "/abc/", "abc", "")
test("/abc/gim\n", "/abc/gim", "abc", "gim")
test("/abc/;\n", "/abc/", "abc", "")
test("/abc/gim;\n", "/abc/gim", "abc", "gim")
})
}

func TestPosition(t *testing.T) {
tt(t, func() {
parser := newParser("", "// Lorem ipsum", 1, nil)
Expand Down

0 comments on commit f2e254a

Please sign in to comment.