From c70084517467aaa8f727e51bebf3a39b23121694 Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Mon, 22 Jun 2020 14:18:14 -0400 Subject: [PATCH] resolve hang on malformed input involving `and` and `or` --- src/parse/value.rs | 26 +++++++++++++++++--------- tests/and.rs | 5 +++++ tests/or.rs | 4 ++++ 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/parse/value.rs b/src/parse/value.rs index 47ff462..9d54dfb 100644 --- a/src/parse/value.rs +++ b/src/parse/value.rs @@ -546,10 +546,12 @@ impl<'a> Parser<'a> { } ';' | '}' | '{' => return None, ':' | '?' | ')' | '@' | '^' | ']' | '|' => { - return Some(Err(("expected \";\".", span).into())) + self.toks.next(); + return Some(Err(("expected \";\".", span).into())); } '\u{0}'..='\u{8}' | '\u{b}'..='\u{1f}' | '\u{7f}'..=std::char::MAX | '`' | '~' => { - return Some(Err(("Expected expression.", span).into())) + self.toks.next(); + return Some(Err(("Expected expression.", span).into())); } ' ' | '\n' | '\t' => unreachable!("whitespace is checked prior to this match"), 'A'..='Z' | 'a'..='z' | '_' | '\\' => { @@ -1194,14 +1196,20 @@ impl<'a, 'b: 'a> IntermediateValueIterator<'a, 'b> { if left.node.is_true(left.span)? { // we explicitly ignore errors here as a workaround for short circuiting while let Some(value) = self.peek() { - if let Ok(Spanned { - node: IntermediateValue::Comma, - .. - }) = value - { - break; + match value { + Ok(Spanned { + node: IntermediateValue::Comma, + .. + }) => break, + Ok(..) => { + self.next(); + } + Err(..) => { + if let Some(v) = self.next() { + v?; + } + } } - self.next(); } space_separated.push(left); } else { diff --git a/tests/and.rs b/tests/and.rs index a3d9e4a..429902b 100644 --- a/tests/and.rs +++ b/tests/and.rs @@ -56,3 +56,8 @@ test!( "a {\n color: false and comparable(\"a\", \"b\");\n}\n", "a {\n color: false;\n}\n" ); +error!( + #[ignore = "blocked on a rewrite of value eval"] + properly_bubbles_error_when_invalid_char_after_and, + "a {\n color: false and? foo;\n}\n", "Error: expected \";\"." +); diff --git a/tests/or.rs b/tests/or.rs index 6caeca2..701761d 100644 --- a/tests/or.rs +++ b/tests/or.rs @@ -73,3 +73,7 @@ test!( "a {\n color: true or red % foo, red;\n}\n", "a {\n color: true, red;\n}\n" ); +error!( + properly_bubbles_error_when_invalid_char_after_or, + "a {\n color: true or? foo;\n}\n", "Error: expected \";\"." +);