mirror of
https://github.com/nushell/nushell.git
synced 2024-11-07 17:14:23 +01:00
Incorrect parsing of unbalanced braces based on issue 6914 (#7621)
This commit is contained in:
parent
ef660be285
commit
0bb2e47c98
@ -396,7 +396,7 @@ proptest! {
|
||||
{{"{0}": "sam"}} | to nuon | from nuon;
|
||||
"#, c).as_ref()
|
||||
));
|
||||
assert!(actual.err.is_empty() || actual.err.contains("Unexpected end of code") || actual.err.contains("only strings can be keys"));
|
||||
assert!(actual.err.is_empty() || actual.err.contains("Unexpected end of code") || actual.err.contains("only strings can be keys") || actual.err.contains("unbalanced { and }"));
|
||||
// The second is for weird escapes due to backslashes
|
||||
// The third is for chars like '0'
|
||||
}
|
||||
|
@ -34,6 +34,10 @@ pub enum ParseError {
|
||||
#[diagnostic(code(nu::parser::unclosed_delimiter), url(docsrs))]
|
||||
Unclosed(String, #[label("unclosed {0}")] Span),
|
||||
|
||||
#[error("Unbalanced delimiter.")]
|
||||
#[diagnostic(code(nu::parser::unbalanced_delimiter), url(docsrs))]
|
||||
Unbalanced(String, String, #[label("unbalanced {0} and {1}")] Span),
|
||||
|
||||
#[error("Parse mismatch during operation.")]
|
||||
#[diagnostic(code(nu::parser::parse_mismatch), url(docsrs))]
|
||||
Expected(String, #[label("expected {0}")] Span),
|
||||
@ -450,6 +454,7 @@ impl ParseError {
|
||||
ParseError::ExtraPositional(_, s) => *s,
|
||||
ParseError::UnexpectedEof(_, s) => *s,
|
||||
ParseError::Unclosed(_, s) => *s,
|
||||
ParseError::Unbalanced(_, _, s) => *s,
|
||||
ParseError::Expected(_, s) => *s,
|
||||
ParseError::Mismatch(_, _, s) => *s,
|
||||
ParseError::UnsupportedOperation(_, _, _, s, _) => *s,
|
||||
|
@ -170,6 +170,23 @@ pub fn lex_item(
|
||||
// We encountered a closing `}` delimiter. Pop off the opening `{`.
|
||||
if let Some(BlockKind::CurlyBracket) = 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),
|
||||
)),
|
||||
);
|
||||
}
|
||||
} else if c == b'(' {
|
||||
// We encountered an opening `(` delimiter.
|
||||
|
@ -4392,10 +4392,15 @@ pub fn parse_value(
|
||||
}
|
||||
b'{' => {
|
||||
if !matches!(shape, SyntaxShape::Closure(..)) && !matches!(shape, SyntaxShape::Block) {
|
||||
if let (expr, None) =
|
||||
parse_full_cell_path(working_set, None, span, expand_aliases_denylist)
|
||||
{
|
||||
return (expr, None);
|
||||
let (expr, err) =
|
||||
parse_full_cell_path(working_set, None, span, expand_aliases_denylist);
|
||||
match err {
|
||||
Some(err) => {
|
||||
if let ParseError::Unbalanced(_, _, _) = err {
|
||||
return (expr, Some(err));
|
||||
}
|
||||
}
|
||||
None => return (expr, None),
|
||||
}
|
||||
}
|
||||
if matches!(shape, SyntaxShape::Closure(_)) || matches!(shape, SyntaxShape::Any) {
|
||||
|
@ -470,3 +470,8 @@ fn or_and_xor() -> TestResult {
|
||||
// Assumes the precedence NOT > AND > XOR > OR
|
||||
run_test(r#"true or false xor true or false"#, "true")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unbalanced_delimiter() -> TestResult {
|
||||
fail_test(r#"{a:{b:5}}}"#, "unbalanced { and }")
|
||||
}
|
||||
|
@ -2,4 +2,4 @@ export def foo [] { "foo" }
|
||||
|
||||
export alias bar = "bar"
|
||||
|
||||
export-env { let-env BAZ = "baz" } }
|
||||
export-env { let-env BAZ = "baz" }
|
||||
|
Loading…
Reference in New Issue
Block a user