From 45f62215abd1a00334604a51b75cba023908b7b4 Mon Sep 17 00:00:00 2001 From: Robert Mosolgo Date: Fri, 6 Sep 2024 09:54:46 -0400 Subject: [PATCH] Handle minus followed by identifier --- lib/graphql/language/lexer.rb | 25 ++++++++++++++----------- spec/graphql/language/parser_spec.rb | 14 +++++++++++++- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/lib/graphql/language/lexer.rb b/lib/graphql/language/lexer.rb index f78ffa06a7..871824465b 100644 --- a/lib/graphql/language/lexer.rb +++ b/lib/graphql/language/lexer.rb @@ -57,20 +57,23 @@ def advance @scanner.skip(IDENTIFIER_REGEXP) :IDENTIFIER when ByteFor::NUMBER - @scanner.skip(NUMERIC_REGEXP) + if len = @scanner.skip(NUMERIC_REGEXP) - if GraphQL.reject_numbers_followed_by_names - new_pos = @scanner.pos - peek_byte = @string.getbyte(new_pos) - next_first_byte = FIRST_BYTES[peek_byte] - if next_first_byte == ByteFor::NAME || next_first_byte == ByteFor::IDENTIFIER - number_part = token_value - name_part = @scanner.scan(IDENTIFIER_REGEXP) - raise_parse_error("Name after number is not allowed (in `#{number_part}#{name_part}`)") + if GraphQL.reject_numbers_followed_by_names + new_pos = @scanner.pos + peek_byte = @string.getbyte(new_pos) + next_first_byte = FIRST_BYTES[peek_byte] + if next_first_byte == ByteFor::NAME || next_first_byte == ByteFor::IDENTIFIER + number_part = token_value + name_part = @scanner.scan(IDENTIFIER_REGEXP) + raise_parse_error("Name after number is not allowed (in `#{number_part}#{name_part}`)") + end end + # Check for a matched decimal: + @scanner[1] ? :FLOAT : :INT + else + raise_parse_error("Expected a number, but it was malformed (#{@string[@pos].inspect})") end - # Check for a matched decimal: - @scanner[1] ? :FLOAT : :INT when ByteFor::ELLIPSIS if @string.getbyte(@pos + 1) != 46 || @string.getbyte(@pos + 2) != 46 raise_parse_error("Expected `...`, actual: #{@string[@pos..@pos + 2].inspect}") diff --git a/spec/graphql/language/parser_spec.rb b/spec/graphql/language/parser_spec.rb index 860e5a3460..c3feafcc5a 100644 --- a/spec/graphql/language/parser_spec.rb +++ b/spec/graphql/language/parser_spec.rb @@ -109,6 +109,18 @@ assert_instance_of GraphQL::Language::Nodes::Enum, doc.definitions.first.selections.first.arguments.first.value end + it "handles invalid minus signs" do + err = assert_raises GraphQL::ParseError do + GraphQL.parse("{ a(b: -c) }") + end + expected_message = if USING_C_PARSER + "syntax error, unexpected invalid token (\"-\") at [1, 8]" + else + "Expected a number, but it was malformed (\"-\")" + end + assert_equal expected_message, err.message + end + it "allows operation names to match operation types" do doc = GraphQL.parse("query subscription { foo }") assert_equal "subscription", doc.definitions.first.name @@ -180,7 +192,7 @@ expected_msg = if USING_C_PARSER "syntax error, unexpected invalid token (\"-\") at [1, 19]" else - "Expected NAME, actual: INT (\"-\") at [1, 19]" + "Expected a number, but it was malformed (\"-\")" end assert_equal expected_msg, err.message