From 48fca1c151f6f734087b34d4656f91e1e239ad2c Mon Sep 17 00:00:00 2001 From: dj-sourbrough <56027726+dj-sourbrough@users.noreply.github.com> Date: Thu, 7 Mar 2024 13:05:04 +0100 Subject: [PATCH] Fix: lex now throws error on unbalanced closing parentheses (issue #11982) (#12098) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fixes issue #11982 # Description Expressions with unbalanced parenthesis [excess closing ')' parenthesis] will throw an error instead of interpreting ')' as a string. Solved he same way as closing braces '}' are handled. ![Screenshot 2024-03-06 at 14 53 46](https://github.com/nushell/nushell/assets/56027726/86834e47-a1e5-484d-881d-0e3b80fecef8) ![Screenshot 2024-03-06 at 14 48 27](https://github.com/nushell/nushell/assets/56027726/bb27c969-6a3b-4735-8a1e-a5881d9096d3) # User-Facing Changes - Trailing closing parentheses ')' which do not match the number of opening parentheses '(' will lead to a parse error. - From what I have found in the documentation this is the intended behavior, thus no documentation has been updated on my part # Tests + Formatting - Two tests added in src/tests/test_parser.rs - All previous tests are still passing - cargo fmt, clippy and test have been run Unable to get the following command run - `cargo run -- -c "use std testing; testing run-tests --path crates/nu-std"` to run the tests for the standard library ![Screenshot 2024-03-06 at 20 06 25](https://github.com/nushell/nushell/assets/56027726/91724fb9-d7d0-472b-bf14-bfa2a7618d09) --------- Co-authored-by: Noak Jönsson --- crates/nu-parser/src/lex.rs | 17 +++++++++++++++++ src/tests/test_parser.rs | 10 ++++++++++ 2 files changed, 27 insertions(+) diff --git a/crates/nu-parser/src/lex.rs b/crates/nu-parser/src/lex.rs index 42f0fa85da..399afb428e 100644 --- a/crates/nu-parser/src/lex.rs +++ b/crates/nu-parser/src/lex.rs @@ -207,6 +207,23 @@ pub fn lex_item( // We encountered a closing `)` delimiter. Pop off the opening `(`. if let Some(BlockKind::Paren) = block_level.last() { let _ = block_level.pop(); + } else { + // We encountered a closing `)` delimiter, but the last opening + // delimiter was not a `(`. This is an error. + let span = Span::new(span_offset + token_start, span_offset + *curr_offset); + + *curr_offset += 1; + return ( + Token { + contents: TokenContents::Item, + span, + }, + Some(ParseError::Unbalanced( + "(".to_string(), + ")".to_string(), + Span::new(span.end, span.end + 1), + )), + ); } } else if is_item_terminator(&block_level, c, additional_whitespace, special_tokens) { break; diff --git a/src/tests/test_parser.rs b/src/tests/test_parser.rs index 6f1224a031..83fc7aa339 100644 --- a/src/tests/test_parser.rs +++ b/src/tests/test_parser.rs @@ -550,6 +550,16 @@ fn unbalanced_delimiter4() -> TestResult { fail_test(r#"}"#, "unbalanced { and }") } +#[test] +fn unbalanced_parens1() -> TestResult { + fail_test(r#")"#, "unbalanced ( and )") +} + +#[test] +fn unbalanced_parens2() -> TestResult { + fail_test(r#"("("))"#, "unbalanced ( and )") +} + #[test] fn register_with_string_literal() -> TestResult { fail_test(r#"register 'nu-plugin-math'"#, "File not found")