From 46e47404a8734efd7f312e29e2fb705dd2f40291 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Tue, 29 Aug 2023 22:40:29 -0400 Subject: [PATCH] [ruby/yarp] fix: trailing decimal, binary, octal, and hex numbers at end of file Previously this resulted in invalid memory access. Found by the fuzzer. https://github.com/ruby/yarp/commit/af5b85a27a --- test/yarp/fuzzer_test.rb | 4 ++++ yarp/yarp.c | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/test/yarp/fuzzer_test.rb b/test/yarp/fuzzer_test.rb index 97f128f08b..6f8cde0d09 100644 --- a/test/yarp/fuzzer_test.rb +++ b/test/yarp/fuzzer_test.rb @@ -17,4 +17,8 @@ class FuzzerTest < Test::Unit::TestCase snippet "incomplete escaped string", '"\\' snippet "trailing comment", "1\n#\n" snippet "trailing asterisk", "a *" + snippet "incomplete decimal number", "0d" + snippet "incomplete binary number", "0b" + snippet "incomplete octal number", "0o" + snippet "incomplete hex number", "0x" end diff --git a/yarp/yarp.c b/yarp/yarp.c index 0d6b55a65e..6b2a3c64e8 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -4997,7 +4997,8 @@ lex_numeric_prefix(yp_parser_t *parser) { // 0d1111 is a decimal number case 'd': case 'D': - if (yp_char_is_decimal_digit(*++parser->current.end)) { + parser->current.end++; + if (yp_char_is_decimal_digit(peek(parser))) { parser->current.end += yp_strspn_decimal_number(parser->current.end, parser->end - parser->current.end); } else { yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid decimal number."); @@ -5008,7 +5009,8 @@ lex_numeric_prefix(yp_parser_t *parser) { // 0b1111 is a binary number case 'b': case 'B': - if (yp_char_is_binary_digit(*++parser->current.end)) { + parser->current.end++; + if (yp_char_is_binary_digit(peek(parser))) { parser->current.end += yp_strspn_binary_number(parser->current.end, parser->end - parser->current.end); } else { yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid binary number."); @@ -5019,7 +5021,8 @@ lex_numeric_prefix(yp_parser_t *parser) { // 0o1111 is an octal number case 'o': case 'O': - if (yp_char_is_octal_digit(*++parser->current.end)) { + parser->current.end++; + if (yp_char_is_octal_digit(peek(parser))) { parser->current.end += yp_strspn_octal_number(parser->current.end, parser->end - parser->current.end); } else { yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid octal number."); @@ -5043,7 +5046,8 @@ lex_numeric_prefix(yp_parser_t *parser) { // 0x1111 is a hexadecimal number case 'x': case 'X': - if (yp_char_is_hexadecimal_digit(*++parser->current.end)) { + parser->current.end++; + if (yp_char_is_hexadecimal_digit(peek(parser))) { parser->current.end += yp_strspn_hexadecimal_number(parser->current.end, parser->end - parser->current.end); } else { yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid hexadecimal number.");