[PATCH v2 0/1] MR10757: vbscript: Fix call depth decrement on early returns from exec_script.
The early-return paths in exec_script skip the call_depth decrement that the normal exit path performs, so any of them leak the depth counter and can spuriously trigger VBSE_OUT_OF_STACK. This is a fix for a regression introduced in !10592 -- v2: vbscript: Decrement call depth on early returns from exec_script. https://gitlab.winehq.org/wine/wine/-/merge_requests/10757
From: Francis De Brabandere <francisdb@gmail.com> The early-return paths in exec_script skip the call_depth decrement that the normal exit path performs, so any of them leak the depth counter and can spuriously trigger VBSE_OUT_OF_STACK. --- dlls/vbscript/interp.c | 5 +++++ dlls/vbscript/tests/lang.vbs | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index a71901a1d83..778689e0eb8 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -2705,6 +2705,7 @@ HRESULT exec_script(script_ctx_t *ctx, BOOL extern_caller, function_t *func, vbd if(dp ? func->arg_cnt != arg_cnt(dp) : func->arg_cnt) { WARN("wrong arg_cnt %d, expected %d\n", dp ? arg_cnt(dp) : 0, func->arg_cnt); + if(!extern_caller) ctx->call_depth--; return MAKE_VBSERROR(VBSE_FUNC_ARITY_MISMATCH); } @@ -2718,6 +2719,7 @@ HRESULT exec_script(script_ctx_t *ctx, BOOL extern_caller, function_t *func, vbd exec.args = calloc(func->arg_cnt, sizeof(VARIANT)); if(!exec.args) { release_exec(&exec); + if(!extern_caller) ctx->call_depth--; return E_OUTOFMEMORY; } @@ -2734,6 +2736,7 @@ HRESULT exec_script(script_ctx_t *ctx, BOOL extern_caller, function_t *func, vbd } if(FAILED(hres)) { release_exec(&exec); + if(!extern_caller) ctx->call_depth--; return hres; } } @@ -2745,6 +2748,7 @@ HRESULT exec_script(script_ctx_t *ctx, BOOL extern_caller, function_t *func, vbd exec.vars = calloc(func->var_cnt, sizeof(VARIANT)); if(!exec.vars) { release_exec(&exec); + if(!extern_caller) ctx->call_depth--; return E_OUTOFMEMORY; } }else { @@ -2756,6 +2760,7 @@ HRESULT exec_script(script_ctx_t *ctx, BOOL extern_caller, function_t *func, vbd exec.stack = malloc(exec.stack_size * sizeof(VARIANT)); if(!exec.stack) { release_exec(&exec); + if(!extern_caller) ctx->call_depth--; return E_OUTOFMEMORY; } diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index d139a2bf282..38b6db85542 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -3015,6 +3015,24 @@ RecurseForever Call ok(Err.Number = 28, "infinite recursion: err.number = " & Err.Number) On Error GoTo 0 +' Regression: early-return paths in exec_script must not leak +' ctx->call_depth, otherwise a hot loop of arity-mismatch calls under +' OERN saturates the limit and breaks every later call. +Sub callDepthLeakProbe(a, b, c) +End Sub +Sub callDepthLeakSink() +End Sub +Dim callDepthLeakI +On Error Resume Next +For callDepthLeakI = 1 To 1100 + Err.Clear + callDepthLeakProbe +Next +Err.Clear +callDepthLeakSink +Call ok(Err.Number = 0, "call_depth leak after arity-mismatch flood: err.number = " & Err.Number) +On Error GoTo 0 + function f2(x,y) end function -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10757
@jacek this is a serious regression that needs a fix asap. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10757#note_137799
participants (2)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb)