Module: wine Branch: master Commit: eeecf6f034ff72cb3ba3285227beb70bd9b82a37 URL: https://gitlab.winehq.org/wine/wine/-/commit/eeecf6f034ff72cb3ba3285227beb70...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Thu Nov 17 10:27:53 2022 +0300
vbscript: Handle index read access to array properties.
Described by Jason Millard.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53867 Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
---
dlls/vbscript/interp.c | 6 +++--- dlls/vbscript/tests/lang.vbs | 13 +++++++++++++ dlls/vbscript/vbdisp.c | 13 +++++++++++-- dlls/vbscript/vbscript.h | 1 + 4 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index 4cfe9596b0c..77875ee7f44 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -535,7 +535,7 @@ static void vbstack_to_dp(exec_ctx_t *ctx, unsigned arg_cnt, BOOL is_propput, DI } }
-static HRESULT array_access(exec_ctx_t *ctx, SAFEARRAY *array, DISPPARAMS *dp, VARIANT **ret) +HRESULT array_access(SAFEARRAY *array, DISPPARAMS *dp, VARIANT **ret) { unsigned i, argc = arg_cnt(dp); LONG *indices; @@ -611,7 +611,7 @@ static HRESULT variant_call(exec_ctx_t *ctx, VARIANT *v, unsigned arg_cnt, VARIA }
vbstack_to_dp(ctx, arg_cnt, FALSE, &dp); - hres = array_access(ctx, array, &dp, &v); + hres = array_access(array, &dp, &v); if(FAILED(hres)) return hres;
@@ -894,7 +894,7 @@ static HRESULT assign_ident(exec_ctx_t *ctx, BSTR name, WORD flags, DISPPARAMS * return E_FAIL; }
- hres = array_access(ctx, array, dp, &v); + hres = array_access(array, dp, &v); if(FAILED(hres)) return hres; }else if(V_VT(v) == (VT_ARRAY|VT_BYREF|VT_VARIANT)) { diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 61258355496..beb7c7e86c9 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -1004,6 +1004,7 @@ Call ok(getVT(x) = "VT_DISPATCH*", "getVT(x) = " & getVT(x))
Class TestClass Public publicProp + Public publicArrayProp
Private privateProp
@@ -1058,6 +1059,11 @@ Class TestClass
Public Sub Class_Initialize publicProp2 = 2 + ReDim publicArrayProp(2) + + publicArrayProp(0) = 1 + publicArrayProp(1) = 2 + privateProp = true Call ok(getVT(privateProp) = "VT_BOOL*", "getVT(privateProp) = " & getVT(privateProp)) Call ok(getVT(publicProp2) = "VT_I2*", "getVT(publicProp2) = " & getVT(publicProp2)) @@ -1110,6 +1116,13 @@ Call ok(funcCalled = "GetDefVal", "funcCalled = " & funcCalled) Call obj.Class_Initialize Call ok(obj.getPrivateProp() = true, "obj.getPrivateProp() = " & obj.getPrivateProp())
+'Accessing array property by index +Call ok(obj.publicArrayProp(0) = 1, "obj.publicArrayProp(0) = " & obj.publicArrayProp(0)) +Call ok(obj.publicArrayProp(1) = 2, "obj.publicArrayProp(1) = " & obj.publicArrayProp(1)) +x = obj.publicArrayProp(2) +Call ok(getVT(x) = "VT_EMPTY*", "getVT(x) = " & getVT(x)) +Call ok(obj.publicArrayProp("0") = 1, "obj.publicArrayProp(0) = " & obj.publicArrayProp("0")) + x = (New testclass).publicProp
Class TermTest diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c index 92468d37ef2..e19ed2b53d4 100644 --- a/dlls/vbscript/vbdisp.c +++ b/dlls/vbscript/vbdisp.c @@ -122,8 +122,17 @@ static HRESULT invoke_variant_prop(script_ctx_t *ctx, VARIANT *v, WORD flags, DI case DISPATCH_PROPERTYGET|DISPATCH_METHOD: case DISPATCH_PROPERTYGET: if(dp->cArgs) { - WARN("called with arguments\n"); - return DISP_E_MEMBERNOTFOUND; /* That's what tests show */ + if (!V_ISARRAY(v)) + { + WARN("called with arguments for non-array property\n"); + return DISP_E_MEMBERNOTFOUND; /* That's what tests show */ + } + + if (FAILED(hres = array_access(V_ARRAY(v), dp, &v))) + { + WARN("failed to access array element\n"); + return hres; + } }
hres = VariantCopyInd(res, v); diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index 2d51c3297f6..3690fc4f0e2 100644 --- a/dlls/vbscript/vbscript.h +++ b/dlls/vbscript/vbscript.h @@ -383,6 +383,7 @@ void clear_ei(EXCEPINFO*) DECLSPEC_HIDDEN; HRESULT report_script_error(script_ctx_t*,const vbscode_t*,unsigned) DECLSPEC_HIDDEN; void detach_global_objects(script_ctx_t*) DECLSPEC_HIDDEN; HRESULT get_builtin_id(BuiltinDisp*,const WCHAR*,DISPID*) DECLSPEC_HIDDEN; +HRESULT array_access(SAFEARRAY *array, DISPPARAMS *dp, VARIANT **ret) DECLSPEC_HIDDEN;
void release_regexp_typelib(void) DECLSPEC_HIDDEN; HRESULT get_dispatch_typeinfo(ITypeInfo**) DECLSPEC_HIDDEN;