From 03420c330eae38c36ecf5adf82d6b89cc6e94cb8 Mon Sep 17 00:00:00 2001 From: roife Date: Wed, 6 Mar 2024 22:50:29 +0800 Subject: [PATCH 1/3] fix: panic when split float numbers in scientific notation --- crates/parser/src/shortcuts.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/crates/parser/src/shortcuts.rs b/crates/parser/src/shortcuts.rs index 680a70997d..2beb3c3ef0 100644 --- a/crates/parser/src/shortcuts.rs +++ b/crates/parser/src/shortcuts.rs @@ -190,7 +190,7 @@ impl Builder<'_, '_> { fn do_float_split(&mut self, has_pseudo_dot: bool) { let text = &self.lexed.range_text(self.pos..self.pos + 1); - self.pos += 1; + match text.split_once('.') { Some((left, right)) => { assert!(!left.is_empty()); @@ -216,8 +216,26 @@ impl Builder<'_, '_> { self.state = State::PendingExit; } } - None => unreachable!(), + None => { + // illegal float literal which doesn't have dot in form (like 1e0) + // we should emit an error node here + (self.sink)(StrStep::Error { msg: "illegal float literal", pos: self.pos }); + (self.sink)(StrStep::Enter { kind: SyntaxKind::ERROR }); + (self.sink)(StrStep::Token { kind: SyntaxKind::FLOAT_NUMBER, text: text }); + (self.sink)(StrStep::Exit); + + // move up + (self.sink)(StrStep::Exit); + + self.state = if has_pseudo_dot { + State::Normal + } else { + State::PendingExit + }; + } } + + self.pos += 1; } } From e2daee61bcc15dde70c9d2ee4d1c86207a5e83ea Mon Sep 17 00:00:00 2001 From: roife Date: Wed, 6 Mar 2024 22:51:22 +0800 Subject: [PATCH 2/3] test: add test for float_split_scientific_notation --- .../0054_float_split_scientific_notation.rast | 88 +++++++++++++++++++ .../0054_float_split_scientific_notation.rs | 5 ++ 2 files changed, 93 insertions(+) create mode 100644 crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rast create mode 100644 crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rs diff --git a/crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rast b/crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rast new file mode 100644 index 0000000000..d6ad733483 --- /dev/null +++ b/crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rast @@ -0,0 +1,88 @@ +SOURCE_FILE + STRUCT + STRUCT_KW "struct" + WHITESPACE " " + NAME + IDENT "S" + TUPLE_FIELD_LIST + L_PAREN "(" + TUPLE_FIELD + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "i32" + COMMA "," + WHITESPACE " " + TUPLE_FIELD + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "i32" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "f" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE "\n " + LET_STMT + LET_KW "let" + WHITESPACE " " + IDENT_PAT + NAME + IDENT "s" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CALL_EXPR + PATH_EXPR + PATH + PATH_SEGMENT + NAME_REF + IDENT "S" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n " + LET_STMT + LET_KW "let" + WHITESPACE " " + IDENT_PAT + NAME + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + FIELD_EXPR + PATH_EXPR + PATH + PATH_SEGMENT + NAME_REF + IDENT "s" + DOT "." + ERROR + FLOAT_NUMBER "1e0" + SEMICOLON ";" + WHITESPACE "\n" + R_CURLY "}" + WHITESPACE "\n" +error 42: illegal float literal diff --git a/crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rs b/crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rs new file mode 100644 index 0000000000..648ef5e043 --- /dev/null +++ b/crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rs @@ -0,0 +1,5 @@ +struct S(i32, i32); +fn f() { + let s = S(1, 2); + let a = s.1e0; +} From 91d181feffc6970b9cc600c4e43ff9b06276c7b3 Mon Sep 17 00:00:00 2001 From: roife Date: Wed, 6 Mar 2024 23:12:27 +0800 Subject: [PATCH 3/3] minor: fmt and clippy --- crates/parser/src/shortcuts.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/crates/parser/src/shortcuts.rs b/crates/parser/src/shortcuts.rs index 2beb3c3ef0..cc2b63d1e6 100644 --- a/crates/parser/src/shortcuts.rs +++ b/crates/parser/src/shortcuts.rs @@ -221,17 +221,13 @@ impl Builder<'_, '_> { // we should emit an error node here (self.sink)(StrStep::Error { msg: "illegal float literal", pos: self.pos }); (self.sink)(StrStep::Enter { kind: SyntaxKind::ERROR }); - (self.sink)(StrStep::Token { kind: SyntaxKind::FLOAT_NUMBER, text: text }); + (self.sink)(StrStep::Token { kind: SyntaxKind::FLOAT_NUMBER, text }); (self.sink)(StrStep::Exit); // move up (self.sink)(StrStep::Exit); - self.state = if has_pseudo_dot { - State::Normal - } else { - State::PendingExit - }; + self.state = if has_pseudo_dot { State::Normal } else { State::PendingExit }; } }