Skip to content

Commit

Permalink
Show proper syntax errors in some edge cases in the parser
Browse files Browse the repository at this point in the history
* A backslash in a regex at the end of the source code was a crash.
* A regex capture `$123` with too big of an integer was a crash.
  • Loading branch information
oprypin committed Nov 12, 2021
1 parent 170d737 commit 2522c1e
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 1 deletion.
1 change: 1 addition & 0 deletions spec/compiler/lexer/lexer_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ describe "Lexer" do
end

assert_syntax_error "/foo", "Unterminated regular expression"
assert_syntax_error "/\\", "Unterminated regular expression"
assert_syntax_error ":\"foo", "unterminated quoted symbol"

it "lexes utf-8 char" do
Expand Down
3 changes: 3 additions & 0 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,9 @@ module Crystal
it_parses "foo $1", Call.new(nil, "foo", Call.new(Global.new("$~"), "[]", 1.int32))
it_parses "$~ = 1", Assign.new("$~".var, 1.int32)

assert_syntax_error "$2147483648"
assert_syntax_error "$99999999999999999999999?", "Regex capture index 99999999999999999999999 doesn't fit in an Int32"

it_parses "foo /a/", Call.new(nil, "foo", regex("a"))
it_parses "foo(/a/)", Call.new(nil, "foo", regex("a"))
it_parses "foo(//)", Call.new(nil, "foo", regex(""))
Expand Down
1 change: 1 addition & 0 deletions src/compiler/crystal/syntax/lexer.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2019,6 +2019,7 @@ module Crystal
if delimiter_state.allow_escapes
if delimiter_state.kind == :regex
char = next_char
raise_unterminated_quoted delimiter_state if char == '\0'
next_char
@token.type = :STRING
if char == '/' || char.ascii_whitespace?
Expand Down
4 changes: 3 additions & 1 deletion src/compiler/crystal/syntax/parser.cr
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,9 @@ module Crystal
method = "[]"
end
location = @token.location
node_and_next_token Call.new(Global.new("$~").at(location), method, NumberLiteral.new(value.to_i))
index = value.to_i?
raise "Regex capture index #{value} doesn't fit in an Int32" unless index
node_and_next_token Call.new(Global.new("$~").at(location), method, NumberLiteral.new(index))
when :__LINE__
node_and_next_token MagicConstant.expand_line_node(@token.location)
when :__END_LINE__
Expand Down

0 comments on commit 2522c1e

Please sign in to comment.