Skip to content

Commit

Permalink
Merge pull request crystal-lang#7886 from oprypin/fuzz1
Browse files Browse the repository at this point in the history
Fix edge cases in code parser and stringifier (found by fuzzing)
  • Loading branch information
straight-shoota authored Jun 14, 2019
2 parents c68418e + f595b1c commit 2595905
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 5 deletions.
8 changes: 8 additions & 0 deletions spec/compiler/lexer/lexer_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ describe "Lexer" do
it_lexes_i64 ["2147483648", "-2147483649"]
it_lexes_i64 [["2147483648.foo", "2147483648"]]
it_lexes_u64 ["18446744073709551615", "14146167139683460000", "9223372036854775808"]
it_lexes_number :u64, ["10000000000000000000_u64", "10000000000000000000"]

it_lexes_i64 [["0x3fffffffffffffff", "4611686018427387903"]]
it_lexes_i64 ["-9223372036854775808", "9223372036854775807"]
it_lexes_u64 [["0xffffffffffffffff", "18446744073709551615"]]
Expand Down Expand Up @@ -294,8 +296,12 @@ describe "Lexer" do
assert_syntax_error "18446744073709551616_u64", "18446744073709551616 doesn't fit in an UInt64"
assert_syntax_error "-1_u64", "Invalid negative value -1 for UInt64"

assert_syntax_error "18446744073709551616_i32", "18446744073709551616 doesn't fit in an Int32"
assert_syntax_error "9999999999999999999_i32", "9999999999999999999 doesn't fit in an Int32"

assert_syntax_error "-9999999999999999999", "-9999999999999999999 doesn't fit in an Int64"
assert_syntax_error "-99999999999999999999", "-99999999999999999999 doesn't fit in an Int64"
assert_syntax_error "-11111111111111111111", "-11111111111111111111 doesn't fit in an Int64"
assert_syntax_error "-9223372036854775809", "-9223372036854775809 doesn't fit in an Int64"
assert_syntax_error "18446744073709551616", "18446744073709551616 doesn't fit in an UInt64"

Expand Down Expand Up @@ -529,4 +535,6 @@ describe "Lexer" do
it_lexes_string %("\\xFF"), String.new(Bytes[0xFF])
assert_syntax_error %("\\xz"), "invalid hex escape"
assert_syntax_error %("\\x1z"), "invalid hex escape"

assert_syntax_error %("hi\\)
end
2 changes: 2 additions & 0 deletions spec/compiler/parser/to_s_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ describe "ASTNode#to_s" do
expect_to_s %(lib Foo\n struct Foo\n a : Void\n b : Void\n end\nend)
expect_to_s %(lib Foo\n union Foo\n a : Int\n b : Int32\n end\nend)
expect_to_s %(lib Foo\n FOO = 0\nend)
expect_to_s %(lib LibC\n fun getch = "get.char"\nend)
expect_to_s %(enum Foo\n A = 0\n B\nend)
expect_to_s %(alias Foo = Void)
expect_to_s %(alias Foo::Bar = Void)
Expand Down Expand Up @@ -162,4 +163,5 @@ describe "ASTNode#to_s" do
expect_to_s %[..3]
expect_to_s "offsetof(Foo, @bar)"
expect_to_s "def foo(**options, &block)\nend"
expect_to_s "macro foo\n 123\nend"
end
13 changes: 10 additions & 3 deletions src/compiler/crystal/syntax/lexer.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1496,13 +1496,16 @@ module Crystal
end

macro gen_check_int_fits_in_size(type, method, size)
if num_size >= 20
raise_value_doesnt_fit_in "{{type}}", string_value, start
end
if num_size >= {{size}}
int_value = absolute_integer_value(string_value, negative)
max = {{type}}::MAX.{{method}}
max += 1 if negative

if int_value > max
raise "#{string_value} doesn't fit in an {{type}}", @token, (current_pos - start)
raise_value_doesnt_fit_in "{{type}}", string_value, start
end
end
end
Expand All @@ -1511,11 +1514,13 @@ module Crystal
if negative
raise "Invalid negative value #{string_value} for {{type}}"
end

if num_size >= 20
raise_value_doesnt_fit_in "{{type}}", string_value, start
end
if num_size >= {{size}}
int_value = absolute_integer_value(string_value, negative)
if int_value > {{type}}::MAX
raise "#{string_value} doesn't fit in an {{type}}", @token, (current_pos - start)
raise_value_doesnt_fit_in "{{type}}", string_value, start
end
end
end
Expand Down Expand Up @@ -1984,6 +1989,8 @@ module Crystal
end
end
next_string_token delimiter_state
when '\0'
raise_unterminated_quoted delimiter_state
else
@token.type = :STRING
@token.value = current_char.to_s
Expand Down
8 changes: 6 additions & 2 deletions src/compiler/crystal/syntax/to_s.cr
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ module Crystal
newline

inside_macro do
accept_with_indent node.body
accept node.body
end

# newline
Expand Down Expand Up @@ -1146,7 +1146,11 @@ module Crystal
else
@str << node.name
@str << " = "
@str << node.real_name
if Symbol.needs_quotes?(node.real_name)
node.real_name.inspect(@str)
else
@str << node.real_name
end
end
if node.args.size > 0
@str << '('
Expand Down

0 comments on commit 2595905

Please sign in to comment.