Skip to content

Commit

Permalink
Fix stack overflow bug.
Browse files Browse the repository at this point in the history
  • Loading branch information
schungx committed May 22, 2024
1 parent a191b6f commit dc43481
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Bug fixes
* The `sync` feature now works properly in `no-std` builds (thanks [`@misssonder`](https://github.com/misssonder) [874](https://github.com/rhaiscript/rhai/pull/874)).
* More data-race conditions are caught and returned as errors instead of panicking.
* Missing `min` and `max` functions where both operands are floats or `Decimal` are added.
* Fixed stack overflow when calling closures recursively (thanks [`@MageWeiG`](https://github.com/MageWeiG) [880](https://github.com/rhaiscript/rhai/issues/880)).

New features
------------
Expand Down
8 changes: 8 additions & 0 deletions src/func/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,8 @@ impl Engine {
let scope = &mut Scope::new();
let environ = fn_ptr.environ.as_ref().map(<_>::as_ref);

defer! { let orig_level = global.level; global.level += 1 }

self.call_script_fn(
global, caches, scope, None, environ, fn_def, args, true, pos,
)
Expand Down Expand Up @@ -832,6 +834,8 @@ impl Engine {
let this_ptr = Some(target.as_mut());
let environ = environ.as_deref();

defer! { let orig_level = global.level; global.level += 1 }

self.call_script_fn(
global, caches, scope, this_ptr, environ, &fn_def, args, true, pos,
)
Expand Down Expand Up @@ -973,6 +977,8 @@ impl Engine {
let this_ptr = Some(target.as_mut());
let args = &mut call_args.iter_mut().collect::<FnArgsVec<_>>();

defer! { let orig_level = global.level; global.level += 1 }

self.call_script_fn(
global, caches, scope, this_ptr, environ, &fn_def, args, true, pos,
)
Expand Down Expand Up @@ -1083,6 +1089,8 @@ impl Engine {
let scope = &mut Scope::new();
let environ = environ.as_deref();

defer! { let orig_level = global.level; global.level += 1 }

return self.call_script_fn(
global, caches, scope, None, environ, &fn_def, args, true, pos,
);
Expand Down
17 changes: 17 additions & 0 deletions tests/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,23 @@ fn test_stack_overflow_fn_calls() {
.unwrap_err(),
EvalAltResult::ErrorStackOverflow(..)
));

#[cfg(not(feature = "no_function"))]
#[cfg(not(feature = "no_object"))]
assert!(matches!(
*engine
.run(
"
let obj1 = #{
action: || this.action(),
update: |x| this.action()
};
obj1.update(1)
"
)
.unwrap_err(),
EvalAltResult::ErrorStackOverflow(..)
));
}

#[test]
Expand Down

0 comments on commit dc43481

Please sign in to comment.