diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index ba718cc771..07cb718d54 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -2831,6 +2831,17 @@ pub fn parse_string(working_set: &mut StateWorkingSet, span: Span) -> Expression if bytes[0] != b'\'' && bytes[0] != b'"' && bytes[0] != b'`' && bytes.contains(&b'(') { return parse_string_interpolation(working_set, span); } + // Check for unbalanced quotes: + { + if bytes.starts_with(b"\"") && (bytes.len() == 1 || !bytes.ends_with(b"\"")) { + working_set.error(ParseError::Unclosed("\"".into(), span)); + return garbage(working_set, span); + } + if bytes.starts_with(b"\'") && (bytes.len() == 1 || !bytes.ends_with(b"\'")) { + working_set.error(ParseError::Unclosed("\'".into(), span)); + return garbage(working_set, span); + } + } let (s, err) = unescape_unquote_string(bytes, span); if let Some(err) = err { diff --git a/tests/repl/test_strings.rs b/tests/repl/test_strings.rs index 62960fed13..f737c0e48f 100644 --- a/tests/repl/test_strings.rs +++ b/tests/repl/test_strings.rs @@ -36,6 +36,12 @@ fn non_string_in_record() -> TestResult { ) } +#[test] +fn unbalance_string() -> TestResult { + fail_test(r#""aaaab"cc"#, "unclosed \"")?; + fail_test(r#"'aaaab'cc"#, "unclosed '") +} + #[test] fn string_in_valuestream() -> TestResult { run_test(