Gabriel Ivăncescu : jscript: Use to_primitive when getting the default value.

Alexandre Julliard julliard at winehq.org
Wed Nov 24 15:17:18 CST 2021


Module: wine
Branch: master
Commit: 464134c20f81b5ab2892e656c8408fb8b0f3b685
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=464134c20f81b5ab2892e656c8408fb8b0f3b685

Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date:   Wed Nov 24 16:10:34 2021 +0200

jscript: Use to_primitive when getting the default value.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/jscript/dispex.c    | 16 ++++++++-
 dlls/jscript/tests/run.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 107 insertions(+), 1 deletion(-)

diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 5cf1e0aad81..6e1463b1e00 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -1572,6 +1572,8 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
         TRACE("invalid id\n");
         return DISP_E_MEMBERNOTFOUND;
     }
+    if(id == DISPID_VALUE && wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT))
+        prop = NULL;
 
     enter_script(This->ctx, &ei);
 
@@ -1600,7 +1602,14 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
     case DISPATCH_PROPERTYGET: {
         jsval_t r;
 
-        hres = prop_get(This, prop, &r);
+        if(prop)
+            hres = prop_get(This, prop, &r);
+        else {
+            hres = to_primitive(This->ctx, jsval_obj(This), &r, NO_HINT);
+            if(hres == JS_E_TO_PRIMITIVE)
+                hres = DISP_E_MEMBERNOTFOUND;
+        }
+
         if(SUCCEEDED(hres)) {
             hres = jsval_to_variant(r, pvarRes);
             jsval_release(r);
@@ -1611,6 +1620,11 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
         jsval_t val;
         DWORD i;
 
+        if(!prop) {
+            hres = DISP_E_MEMBERNOTFOUND;
+            break;
+        }
+
         for(i=0; i < pdp->cNamedArgs; i++) {
             if(pdp->rgdispidNamedArgs[i] == DISPID_PROPERTYPUT)
                 break;
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c
index ef0f39f1317..0e2f6333abc 100644
--- a/dlls/jscript/tests/run.c
+++ b/dlls/jscript/tests/run.c
@@ -2789,6 +2789,8 @@ static void test_retval(void)
 
 static void test_default_value(void)
 {
+    static DISPID propput_dispid = DISPID_PROPERTYPUT;
+    IActiveScript *script;
     DISPPARAMS dp = {0};
     IDispatch *disp;
     VARIANT v;
@@ -2806,9 +2808,99 @@ static void test_default_value(void)
     {
         ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
     }
+    VariantClear(&v);
+    IDispatch_Release(disp);
+
+    hres = parse_script_expr(L"var arr = [5]; arr.toString = function() {return \"foo\";}; arr.valueOf = function() {return 42;}; arr", &v, &script);
+    ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
+    disp = V_DISPATCH(&v);
+
+    V_VT(&v) = VT_EMPTY;
+    hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL);
+    ok(hres == S_OK, "Invoke failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
+    ok(V_I4(&v) == 42, "V_I4(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
+    IDispatch_Release(disp);
+    close_script(script);
+
+    hres = parse_script_expr(L"var arr = [5]; arr.toString = function() {return \"foo\";}; arr", &v, &script);
+    ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
+    disp = V_DISPATCH(&v);
 
+    V_VT(&v) = VT_EMPTY;
+    hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL);
+    ok(hres == S_OK, "Invoke failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
+    ok(!lstrcmpW(V_BSTR(&v), L"foo"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
     VariantClear(&v);
     IDispatch_Release(disp);
+    close_script(script);
+
+    hres = parse_script_expr(L"var arr = [5]; arr", &v, &script);
+    ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
+    disp = V_DISPATCH(&v);
+
+    V_VT(&v) = VT_EMPTY;
+    hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL);
+    ok(hres == S_OK, "Invoke failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
+    ok(!lstrcmpW(V_BSTR(&v), L"5"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
+    VariantClear(&v);
+    IDispatch_Release(disp);
+    close_script(script);
+
+    hres = parse_script_expr(L"var obj = Object.prototype; delete obj.valueOf; obj", &v, &script);
+    ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
+    disp = V_DISPATCH(&v);
+
+    V_VT(&v) = VT_EMPTY;
+    hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL);
+    ok(hres == S_OK, "Invoke failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
+    ok(!lstrcmpW(V_BSTR(&v), L"[object Object]"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
+    VariantClear(&v);
+    IDispatch_Release(disp);
+    close_script(script);
+
+    hres = parse_script_expr(L"var obj = Object.prototype; delete obj.toString; obj", &v, &script);
+    ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
+    disp = V_DISPATCH(&v);
+
+    V_VT(&v) = VT_EMPTY;
+    hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL);
+    ok(hres == DISP_E_MEMBERNOTFOUND, "Invoke failed: %08x\n", hres);
+    IDispatch_Release(disp);
+    close_script(script);
+
+    hres = parse_script_expr(L"Object.prototype", &v, &script);
+    ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
+    disp = V_DISPATCH(&v);
+
+    dp.cArgs = dp.cNamedArgs = 1;
+    dp.rgdispidNamedArgs = &propput_dispid;
+    dp.rgvarg = &v;
+    V_VT(&v) = VT_EMPTY;
+    hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dp, NULL, NULL, NULL);
+    ok(hres == DISP_E_MEMBERNOTFOUND, "Invoke failed: %08x\n", hres);
+    IDispatch_Release(disp);
+    close_script(script);
+
+    hres = parse_script_expr(L"var f = function() {return 42;}; f", &v, &script);
+    ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
+    disp = V_DISPATCH(&v);
+
+    V_VT(&v) = VT_EMPTY;
+    hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dp, NULL, NULL, NULL);
+    ok(hres == DISP_E_MEMBERNOTFOUND, "Invoke failed: %08x\n", hres);
+    IDispatch_Release(disp);
+    close_script(script);
 }
 
 static void test_script_exprs(void)




More information about the wine-cvs mailing list