Repository: apollographql/apollo-rs
Pull request #646 (2023-09-19 15:21:39)

Fix integer lexing
* A plus sign is an error
* A minus sign followed by EOF without any digit is an error

Found by fuzzing! (New fuzz target upcoming in another PR)


Patch:
diff --git a/crates/apollo-parser/CHANGELOG.md b/crates/apollo-parser/CHANGELOG.md
index 20919b7..a030c9e 100644
--- a/crates/apollo-parser/CHANGELOG.md
+++ b/crates/apollo-parser/CHANGELOG.md
@@ -17,6 +17,14 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
 
 ## Documentation -->
 
+# [x.x.x] (unreleased) - 2023-mm-dd
+## Fixes
+- **fixes lexing of plus and minus signs in numbers - [SimonSapin], [pull/646]**
+  Plus signs are errors in GraphQL syntax.
+  Minus signs are errors if they’re not followed by a digit, even if followed by EOF.
+
+[pull/646]: https://github.com/apollographql/apollo-rs/pull/646
+
 # [0.6.2](https://crates.io/crates/apollo-parser/0.6.2) - 2023-09-08
 ## Fixes
 - **fixes to conversions from AST string nodes to Rust Strings - [goto-bus-stop], [pull/633], [issue/609], [issue/611]**
diff --git a/crates/apollo-parser/src/lexer/mod.rs b/crates/apollo-parser/src/lexer/mod.rs
index f944142..60d2bb7 100644
--- a/crates/apollo-parser/src/lexer/mod.rs
+++ b/crates/apollo-parser/src/lexer/mod.rs
@@ -49,7 +49,7 @@ enum State {
     Whitespace,
     Comment,
     SpreadOperator,
-    PlusMinus,
+    MinusSign,
 }
 
 impl<'a> Lexer<'a> {
@@ -162,9 +162,9 @@ impl<'a> Cursor<'a> {
                             token.kind = TokenKind::Name;
                             state = State::Ident;
                         }
-                        '+' | '-' => {
+                        '-' => {
                             token.kind = TokenKind::Int;
-                            state = State::PlusMinus;
+                            state = State::MinusSign;
                         }
                         c if c.is_ascii_digit() => {
                             token.kind = TokenKind::Int;
@@ -441,7 +441,7 @@ impl<'a> Cursor<'a> {
                     }
                     _ => break,
                 },
-                State::PlusMinus => match c {
+                State::MinusSign => match c {
                     curr if curr.is_ascii_digit() => {
                         state = State::IntLiteral;
                     }
@@ -512,6 +512,10 @@ impl<'a> Cursor<'a> {
                     token.index,
                 ))
             }
+            State::MinusSign => Err(Error::new(
+                "Unexpected character \"-\"",
+                self.current_str().to_string(),
+            )),
             _ => {
                 if let Some(mut err) = self.err() {
                     err.set_data(self.current_str().to_string());


Test patch:
diff --git a/crates/apollo-parser/test_data/lexer/err/0014_plus_sign.graphql b/crates/apollo-parser/test_data/lexer/err/0014_plus_sign.graphql
new file mode 100644
index 0000000..fd71255
--- /dev/null
+++ b/crates/apollo-parser/test_data/lexer/err/0014_plus_sign.graphql
@@ -0,0 +1,1 @@
++1, +
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/lexer/err/0014_plus_sign.txt b/crates/apollo-parser/test_data/lexer/err/0014_plus_sign.txt
new file mode 100644
index 0000000..675a3c1
--- /dev/null
+++ b/crates/apollo-parser/test_data/lexer/err/0014_plus_sign.txt
@@ -0,0 +1,6 @@
+INT@1:2 "1"
+COMMA@2:3 ","
+WHITESPACE@3:4 " "
+EOF@5:5
+ERROR@0:1 "Unexpected character \"+\"" +
+ERROR@0:1 "Unexpected character \"+\"" +
diff --git a/crates/apollo-parser/test_data/lexer/err/0015_minus_sign.graphql b/crates/apollo-parser/test_data/lexer/err/0015_minus_sign.graphql
new file mode 100644
index 0000000..847c099
--- /dev/null
+++ b/crates/apollo-parser/test_data/lexer/err/0015_minus_sign.graphql
@@ -0,0 +1,1 @@
+-1, -
\ No newline at end of file
diff --git a/crates/apollo-parser/test_data/lexer/err/0015_minus_sign.txt b/crates/apollo-parser/test_data/lexer/err/0015_minus_sign.txt
new file mode 100644
index 0000000..09728fb
--- /dev/null
+++ b/crates/apollo-parser/test_data/lexer/err/0015_minus_sign.txt
@@ -0,0 +1,5 @@
+INT@0:2 "-1"
+COMMA@2:3 ","
+WHITESPACE@3:4 " "
+EOF@5:5
+ERROR@0:1 "Unexpected character \"-\"" -