From 94a0819fe3a0d679c3042a77bfe6a2afc505daea Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:11:28 +0200 Subject: Adding upstream version 1.66.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/pest_meta/src/parser.rs | 93 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 17 deletions(-) (limited to 'vendor/pest_meta/src/parser.rs') diff --git a/vendor/pest_meta/src/parser.rs b/vendor/pest_meta/src/parser.rs index 5f6f3b374..72abd810d 100644 --- a/vendor/pest_meta/src/parser.rs +++ b/vendor/pest_meta/src/parser.rs @@ -15,10 +15,14 @@ use pest::iterators::{Pair, Pairs}; use pest::prec_climber::{Assoc, Operator, PrecClimber}; use pest::{Parser, Span}; -use ast::{Expr, Rule as AstRule, RuleType}; -use validator; +use crate::ast::{Expr, Rule as AstRule, RuleType}; +use crate::validator; -include!("grammar.rs"); +mod grammar { + include!("grammar.rs"); +} + +pub use self::grammar::*; pub fn parse(rule: Rule, data: &str) -> Result, Error> { PestParser::parse(rule, data) @@ -125,13 +129,9 @@ pub enum ParserExpr<'i> { } fn convert_rule(rule: ParserRule) -> AstRule { - match rule { - ParserRule { name, ty, node, .. } => { - let expr = convert_node(node); - - AstRule { name, ty, expr } - } - } + let ParserRule { name, ty, node, .. } = rule; + let expr = convert_node(node); + AstRule { name, ty, expr } } fn convert_node(node: ParserNode) -> Expr { @@ -174,9 +174,7 @@ pub fn consume_rules(pairs: Pairs) -> Result, Vec } } -fn consume_rules_with_spans<'i>( - pairs: Pairs<'i, Rule>, -) -> Result>, Vec>> { +fn consume_rules_with_spans(pairs: Pairs) -> Result, Vec>> { let climber = PrecClimber::new(vec![ Operator::new(Rule::choice_operator, Assoc::Left), Operator::new(Rule::sequence_operator, Assoc::Left), @@ -206,7 +204,13 @@ fn consume_rules_with_spans<'i>( pairs.next().unwrap(); // opening_brace - let node = consume_expr(pairs.next().unwrap().into_inner().peekable(), &climber)?; + // skip initial infix operators + let mut inner_nodes = pairs.next().unwrap().into_inner().peekable(); + if inner_nodes.peek().unwrap().as_rule() == Rule::choice_operator { + inner_nodes.next().unwrap(); + } + + let node = consume_expr(inner_nodes, &climber)?; Ok(ParserRule { name, @@ -617,6 +621,8 @@ fn unescape(string: &str) -> Option { #[cfg(test)] mod tests { + use std::convert::TryInto; + use super::super::unwrap_or_report; use super::*; @@ -1073,7 +1079,7 @@ mod tests { parser: PestParser, input: "a = {}", rule: Rule::grammar_rules, - positives: vec![Rule::term], + positives: vec![Rule::expression], negatives: vec![], pos: 5 }; @@ -1091,6 +1097,18 @@ mod tests { }; } + #[test] + fn incorrect_prefix() { + fails_with! { + parser: PestParser, + input: "a = { ~ b}", + rule: Rule::grammar_rules, + positives: vec![Rule::expression], + negatives: vec![], + pos: 6 + }; + } + #[test] fn wrong_op() { fails_with! { @@ -1228,7 +1246,7 @@ mod tests { let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap(); let ast = consume_rules_with_spans(pairs).unwrap(); - let ast: Vec<_> = ast.into_iter().map(|rule| convert_rule(rule)).collect(); + let ast: Vec<_> = ast.into_iter().map(convert_rule).collect(); assert_eq!( ast, @@ -1266,7 +1284,7 @@ mod tests { let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap(); let ast = consume_rules_with_spans(pairs).unwrap(); - let ast: Vec<_> = ast.into_iter().map(|rule| convert_rule(rule)).collect(); + let ast: Vec<_> = ast.into_iter().map(convert_rule).collect(); assert_eq!( ast, @@ -1485,4 +1503,45 @@ mod tests { assert_eq!(unescape(string), None); } + + #[test] + fn handles_deep_nesting() { + let sample1 = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/resources/test/fuzzsample1.grammar" + )); + let sample2 = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/resources/test/fuzzsample2.grammar" + )); + let sample3 = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/resources/test/fuzzsample3.grammar" + )); + let sample4 = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/resources/test/fuzzsample4.grammar" + )); + let sample5 = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/resources/test/fuzzsample5.grammar" + )); + const ERROR: &str = "call limit reached"; + pest::set_call_limit(Some(5_000usize.try_into().unwrap())); + let s1 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample1); + assert!(s1.is_err()); + assert_eq!(s1.unwrap_err().variant.message(), ERROR); + let s2 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample2); + assert!(s2.is_err()); + assert_eq!(s2.unwrap_err().variant.message(), ERROR); + let s3 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample3); + assert!(s3.is_err()); + assert_eq!(s3.unwrap_err().variant.message(), ERROR); + let s4 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample4); + assert!(s4.is_err()); + assert_eq!(s4.unwrap_err().variant.message(), ERROR); + let s5 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample5); + assert!(s5.is_err()); + assert_eq!(s5.unwrap_err().variant.message(), ERROR); + } } -- cgit v1.2.3