diff --git a/native/Cargo.lock b/native/Cargo.lock index 62fb13517..7bd58fff6 100644 --- a/native/Cargo.lock +++ b/native/Cargo.lock @@ -421,8 +421,7 @@ checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" [[package]] name = "peg" version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af728fe826811af3b38c37e93de6d104485953ea373d656eebae53d6987fcd2c" +source = "git+https://github.com/zsol/rust-peg?branch=stackoverflow#b91bd0f673a305d8f62070d11c7e22d7ddbf03fa" dependencies = [ "peg-macros", "peg-runtime", @@ -431,8 +430,7 @@ dependencies = [ [[package]] name = "peg-macros" version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4536be147b770b824895cbad934fccce8e49f14b4c4946eaa46a6e4a12fcdc16" +source = "git+https://github.com/zsol/rust-peg?branch=stackoverflow#b91bd0f673a305d8f62070d11c7e22d7ddbf03fa" dependencies = [ "peg-runtime", "proc-macro2", @@ -442,8 +440,7 @@ dependencies = [ [[package]] name = "peg-runtime" version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9b0efd3ba03c3a409d44d60425f279ec442bcf0b9e63ff4e410da31c8b0f69f" +source = "git+https://github.com/zsol/rust-peg?branch=stackoverflow#b91bd0f673a305d8f62070d11c7e22d7ddbf03fa" [[package]] name = "plotters" diff --git a/native/libcst/Cargo.toml b/native/libcst/Cargo.toml index e3bcad5b9..03edb2db2 100644 --- a/native/libcst/Cargo.toml +++ b/native/libcst/Cargo.toml @@ -30,9 +30,9 @@ trace = ["peg/trace"] [dependencies] paste = "1.0.4" -pyo3 = { version = "0.16.5", optional = true } +pyo3 = { version = "0.16", optional = true } thiserror = "1.0.23" -peg = "0.8.0" +peg = { git = "https://github.com/zsol/rust-peg", branch = "stackoverflow" } chic = "1.2.2" itertools = "0.10.0" once_cell = "1.5.2" diff --git a/native/libcst/src/parser/grammar.rs b/native/libcst/src/parser/grammar.rs index aa7619cb2..3c0ba1380 100644 --- a/native/libcst/src/parser/grammar.rs +++ b/native/libcst/src/parser/grammar.rs @@ -85,9 +85,13 @@ impl<'input, 'a: 'input> ParseElem<'input> for TokVec<'a> { } } +const MAX_RECURSION_DEPTH: usize = 3000; + parser! { pub grammar python<'a>(input: &'a str) for TokVec<'a> { + stack_limit 3000; + // Starting Rules pub rule file(encoding: Option<&str>) -> Module<'input, 'a> @@ -1117,7 +1121,7 @@ parser! { rule strings() -> String<'input, 'a> = s:(str:tok(STRING, "STRING") t:&_ {(make_string(str), t)} - / str:fstring() t:&_ {(String::Formatted(str), t)})+ { + / str:fstring() t:&_ {(String::Formatted(str), t)})+ {? make_strings(s) } @@ -1171,7 +1175,7 @@ parser! { // Comprehensions & generators rule for_if_clauses() -> CompFor<'input, 'a> - = c:for_if_clause()+ { merge_comp_fors(c) } + = c:for_if_clause()+ {? merge_comp_fors(c) } rule for_if_clause() -> CompFor<'input, 'a> = asy:_async() f:lit("for") tgt:star_targets() i:lit("in") @@ -2240,14 +2244,19 @@ fn make_bare_genexp<'input, 'a>( } } -fn merge_comp_fors<'input, 'a>(comp_fors: Vec>) -> CompFor<'input, 'a> { +fn merge_comp_fors<'input, 'a>( + comp_fors: Vec>, +) -> GrammarResult> { + if comp_fors.len() > MAX_RECURSION_DEPTH { + return Err("shallower comprehension"); + } let mut it = comp_fors.into_iter().rev(); let first = it.next().expect("cant merge empty comp_fors"); - it.fold(first, |acc, curr| CompFor { + Ok(it.fold(first, |acc, curr| CompFor { inner_for_in: Some(Box::new(acc)), ..curr - }) + })) } fn make_left_bracket<'input, 'a>(tok: TokenRef<'input, 'a>) -> LeftSquareBracket<'input, 'a> { @@ -2816,10 +2825,13 @@ fn make_string<'input, 'a>(tok: TokenRef<'input, 'a>) -> String<'input, 'a> { fn make_strings<'input, 'a>( s: Vec<(String<'input, 'a>, TokenRef<'input, 'a>)>, -) -> String<'input, 'a> { +) -> GrammarResult> { + if s.len() > MAX_RECURSION_DEPTH { + return Err("shorter concatenated string"); + } let mut strings = s.into_iter().rev(); let (first, _) = strings.next().expect("no strings to make a string of"); - strings.fold(first, |acc, (str, tok)| { + Ok(strings.fold(first, |acc, (str, tok)| { let ret: String<'input, 'a> = String::Concatenated(ConcatenatedString { left: Box::new(str), right: Box::new(acc), @@ -2828,7 +2840,7 @@ fn make_strings<'input, 'a>( right_tok: tok, }); ret - }) + })) } fn make_fstring_expression<'input, 'a>(