From fe58e842716609b461814bffd1b5c942b60e8776 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Fri, 9 Sep 2022 15:09:41 +0200 Subject: [PATCH] fix: Ensure the second stack overflow issue errors Since this test has nested binary expressions it does not overflow the stack or hit the depth checking path in the parser so we also needed the second check. --- libflux/flux-core/src/ast/check/mod.rs | 15 +++++++++++++++ libflux/flux-core/src/parser/tests/errors.rs | 10 ++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/libflux/flux-core/src/ast/check/mod.rs b/libflux/flux-core/src/ast/check/mod.rs index bbc5e147f9..a4bbaf65d2 100644 --- a/libflux/flux-core/src/ast/check/mod.rs +++ b/libflux/flux-core/src/ast/check/mod.rs @@ -11,15 +11,26 @@ use crate::{ /// Inspects an AST node and returns a list of found AST errors plus /// any errors existed before `ast.check()` is performed. pub fn check(node: walk::Node) -> Result<(), Errors> { + const MAX_DEPTH: u32 = 180; + #[derive(Default)] struct Check { + depth: u32, errors: Errors, } impl<'a> walk::Visitor<'a> for Check { fn visit(&mut self, n: walk::Node<'a>) -> bool { + self.depth += 1; + let errors = &mut self.errors; + if self.depth > MAX_DEPTH { + errors.push(located(n.base().location.clone(), ErrorKind::NestedToDeep)); + + return false; + } + // collect any errors we found prior to ast.check(). for err in n.base().errors.iter() { let err = if err == "Program is nested too deep" { @@ -87,6 +98,10 @@ pub fn check(node: walk::Node) -> Result<(), Errors> { true } + + fn done(&mut self, _: walk::Node<'a>) { + self.depth -= 1; + } } let mut check = Check::default(); diff --git a/libflux/flux-core/src/parser/tests/errors.rs b/libflux/flux-core/src/parser/tests/errors.rs index a21dc229a3..010f145166 100644 --- a/libflux/flux-core/src/parser/tests/errors.rs +++ b/libflux/flux-core/src/parser/tests/errors.rs @@ -938,12 +938,18 @@ builtin y : int fn dont_stack_overflow() { let mut p = Parser::new(include_str!("stack_overflow.flux")); let parsed = p.parse_file("".to_string()); - assert!(&ast::check::check(ast::walk::Node::File(&parsed)).is_err()); + assert!(&ast::check::check(ast::walk::Node::File(&parsed)) + .unwrap_err() + .iter() + .any(|err| err.error.is_fatal())); } #[test] fn dont_stack_overflow_2() { let mut p = Parser::new(include_str!("stack_overflow_2.flux")); let parsed = p.parse_file("".to_string()); - assert!(&ast::check::check(ast::walk::Node::File(&parsed)).is_err()); + assert!(&ast::check::check(ast::walk::Node::File(&parsed)) + .unwrap_err() + .iter() + .any(|err| err.error.is_fatal())); }