From 3e14a747fd96f2fcaf03f978bbfb362de26d84c6 Mon Sep 17 00:00:00 2001 From: Kevin Xiao Date: Tue, 18 Jul 2023 20:21:17 -0400 Subject: [PATCH 1/3] Add max recursion depth check --- kalk/src/errors.rs | 2 ++ kalk/src/interpreter.rs | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/kalk/src/errors.rs b/kalk/src/errors.rs index 2e898e5..da2a025 100644 --- a/kalk/src/errors.rs +++ b/kalk/src/errors.rs @@ -19,6 +19,7 @@ pub enum KalkError { InvalidNumberLiteral(String), InvalidOperator, InvalidUnit, + StackOverflow, TimedOut, VariableReferencesItself, PiecewiseConditionsAreFalse, @@ -61,6 +62,7 @@ impl ToString for KalkError { KalkError::InvalidNumberLiteral(x) => format!("Invalid number literal: '{}'.", x), KalkError::InvalidOperator => String::from("Invalid operator."), KalkError::InvalidUnit => String::from("Invalid unit."), + KalkError::StackOverflow => String::from("Operation recursed too deeply."), KalkError::TimedOut => String::from("Operation took too long."), KalkError::VariableReferencesItself => String::from("Variable references itself."), KalkError::PiecewiseConditionsAreFalse => String::from("All the conditions in the piecewise are false."), diff --git a/kalk/src/interpreter.rs b/kalk/src/interpreter.rs index 927837e..045019b 100644 --- a/kalk/src/interpreter.rs +++ b/kalk/src/interpreter.rs @@ -9,6 +9,8 @@ use crate::symbol_table::SymbolTable; use crate::{as_number_or_zero, numerical}; use crate::{float, prelude}; +const DEFAULT_MAX_RECURSION_DEPTH: u32 = 128; + pub struct Context<'a> { pub symbol_table: &'a mut SymbolTable, angle_unit: String, @@ -20,6 +22,8 @@ pub struct Context<'a> { #[cfg(not(target_arch = "wasm32"))] start_time: std::time::SystemTime, is_approximation: bool, + recursion_depth: u32, + max_recursion_depth: u32, } impl<'a> Context<'a> { @@ -40,6 +44,8 @@ impl<'a> Context<'a> { #[cfg(not(target_arch = "wasm32"))] start_time: std::time::SystemTime::now(), is_approximation: false, + recursion_depth: 0, + max_recursion_depth: DEFAULT_MAX_RECURSION_DEPTH, } } @@ -83,6 +89,7 @@ struct SumVar { } fn eval_stmt(context: &mut Context, stmt: &Stmt) -> Result { + context.recursion_depth += 1; match stmt { Stmt::VarDecl(_, _) => eval_var_decl_stmt(context, stmt), Stmt::FnDecl(_, _, _) => eval_fn_decl_stmt(), @@ -506,6 +513,10 @@ pub(crate) fn eval_fn_call_expr( match stmt_definition { Some(Stmt::FnDecl(_, arguments, fn_body)) => { + if context.recursion_depth > context.max_recursion_depth { + return Err(KalkError::StackOverflow); + } + if arguments.len() != expressions.len() { return Err(KalkError::IncorrectAmountOfArguments( arguments.len(), From 3619008188c158f4345290bcfcf4688547504639 Mon Sep 17 00:00:00 2001 From: Kevin Xiao Date: Wed, 19 Jul 2023 16:18:03 -0400 Subject: [PATCH 2/3] Also decrement --- kalk/src/interpreter.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kalk/src/interpreter.rs b/kalk/src/interpreter.rs index 045019b..5d7a115 100644 --- a/kalk/src/interpreter.rs +++ b/kalk/src/interpreter.rs @@ -89,7 +89,6 @@ struct SumVar { } fn eval_stmt(context: &mut Context, stmt: &Stmt) -> Result { - context.recursion_depth += 1; match stmt { Stmt::VarDecl(_, _) => eval_var_decl_stmt(context, stmt), Stmt::FnDecl(_, _, _) => eval_fn_decl_stmt(), @@ -136,7 +135,10 @@ pub(crate) fn eval_expr( Expr::Boolean(value) => Ok(KalkValue::Boolean(*value)), Expr::Group(expr) => eval_group_expr(context, expr, unit), Expr::FnCall(identifier, expressions) => { - eval_fn_call_expr(context, identifier, expressions, unit) + context.recursion_depth += 1; + let res = eval_fn_call_expr(context, identifier, expressions, unit); + context.recursion_depth -= 1; + res } Expr::Piecewise(pieces) => eval_piecewise(context, pieces, unit), Expr::Vector(values) => eval_vector(context, values), @@ -517,6 +519,7 @@ pub(crate) fn eval_fn_call_expr( return Err(KalkError::StackOverflow); } + if arguments.len() != expressions.len() { return Err(KalkError::IncorrectAmountOfArguments( arguments.len(), From 46d8801acaa44374403e04f08710eb59ec809aaa Mon Sep 17 00:00:00 2001 From: Kevin Xiao Date: Wed, 19 Jul 2023 16:18:58 -0400 Subject: [PATCH 3/3] Move recursion check up --- kalk/src/interpreter.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/kalk/src/interpreter.rs b/kalk/src/interpreter.rs index 5d7a115..ef14b22 100644 --- a/kalk/src/interpreter.rs +++ b/kalk/src/interpreter.rs @@ -342,6 +342,10 @@ pub(crate) fn eval_fn_call_expr( expressions: &[Expr], unit: Option<&String>, ) -> Result { + if context.recursion_depth > context.max_recursion_depth { + return Err(KalkError::StackOverflow); + } + if identifier.prime_count > 0 { context.is_approximation = true; } @@ -515,11 +519,6 @@ pub(crate) fn eval_fn_call_expr( match stmt_definition { Some(Stmt::FnDecl(_, arguments, fn_body)) => { - if context.recursion_depth > context.max_recursion_depth { - return Err(KalkError::StackOverflow); - } - - if arguments.len() != expressions.len() { return Err(KalkError::IncorrectAmountOfArguments( arguments.len(),