Skip to content

Commit

Permalink
fix: Ensure the second stack overflow issue errors
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Markus Westerlind committed Sep 9, 2022
1 parent a93b511 commit fe58e84
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
15 changes: 15 additions & 0 deletions libflux/flux-core/src/ast/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Error>> {
const MAX_DEPTH: u32 = 180;

#[derive(Default)]
struct Check {
depth: u32,
errors: Errors<Error>,
}

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" {
Expand Down Expand Up @@ -87,6 +98,10 @@ pub fn check(node: walk::Node) -> Result<(), Errors<Error>> {

true
}

fn done(&mut self, _: walk::Node<'a>) {
self.depth -= 1;
}
}

let mut check = Check::default();
Expand Down
10 changes: 8 additions & 2 deletions libflux/flux-core/src/parser/tests/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
}

0 comments on commit fe58e84

Please sign in to comment.