[PATCH 03/10] jscript: Treat NULL disps as actual null values in html mode.

Gabriel Ivăncescu gabrielopcode at gmail.com
Tue Apr 12 09:47:32 CDT 2022


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/jscript/dispex.c             | 14 +++++++-------
 dlls/jscript/enumerator.c         | 10 +++++-----
 dlls/jscript/jsutils.c            |  8 ++++----
 dlls/jscript/jsval.h              |  2 +-
 dlls/jscript/vbarray.c            |  4 ++--
 dlls/mshtml/tests/documentmode.js |  7 ++-----
 dlls/mshtml/tests/es5.js          |  8 ++++++++
 7 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 7f4d1e1..8682766 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -386,7 +386,7 @@ static IDispatch *get_this(DISPPARAMS *dp)
     return NULL;
 }
 
-static HRESULT convert_params(const DISPPARAMS *dp, jsval_t *buf, unsigned *argc, jsval_t **ret)
+static HRESULT convert_params(script_ctx_t *ctx, const DISPPARAMS *dp, jsval_t *buf, unsigned *argc, jsval_t **ret)
 {
     jsval_t *argv;
     unsigned cnt;
@@ -404,7 +404,7 @@ static HRESULT convert_params(const DISPPARAMS *dp, jsval_t *buf, unsigned *argc
     }
 
     for(i = 0; i < cnt; i++) {
-        hres = variant_to_jsval(dp->rgvarg+dp->cArgs-i-1, argv+i);
+        hres = variant_to_jsval(ctx, dp->rgvarg+dp->cArgs-i-1, argv+i);
         if(FAILED(hres)) {
             while(i--)
                 jsval_release(argv[i]);
@@ -1593,7 +1593,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
         jsval_t *argv, buf[6], r;
         unsigned argc;
 
-        hres = convert_params(pdp, buf, &argc, &argv);
+        hres = convert_params(This->ctx, pdp, buf, &argc, &argv);
         if(FAILED(hres))
             break;
 
@@ -1649,7 +1649,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
             break;
         }
 
-        hres = variant_to_jsval(pdp->rgvarg+i, &val);
+        hres = variant_to_jsval(This->ctx, pdp->rgvarg+i, &val);
         if(FAILED(hres))
             break;
 
@@ -2141,7 +2141,7 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns
         heap_free(dp.rgvarg);
 
     if(SUCCEEDED(hres) && ret)
-        hres = variant_to_jsval(&retv, ret);
+        hres = variant_to_jsval(ctx, &retv, ret);
     VariantClear(&retv);
     return hres;
 }
@@ -2209,7 +2209,7 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
     if(!r)
         return S_OK;
 
-    hres = variant_to_jsval(&retv, r);
+    hres = variant_to_jsval(ctx, &retv, r);
     VariantClear(&retv);
     return hres;
 }
@@ -2385,7 +2385,7 @@ HRESULT disp_propget(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t *val
     V_VT(&var) = VT_EMPTY;
     hres = disp_invoke(ctx, disp, id, INVOKE_PROPERTYGET, &dp, &var);
     if(SUCCEEDED(hres)) {
-        hres = variant_to_jsval(&var, val);
+        hres = variant_to_jsval(ctx, &var, val);
         VariantClear(&var);
     }
     return hres;
diff --git a/dlls/jscript/enumerator.c b/dlls/jscript/enumerator.c
index 0fc6750..94eb9f2 100644
--- a/dlls/jscript/enumerator.c
+++ b/dlls/jscript/enumerator.c
@@ -44,7 +44,7 @@ static inline EnumeratorInstance *enumerator_this(jsval_t vthis)
     return (jsdisp && is_class(jsdisp, JSCLASS_ENUMERATOR)) ? enumerator_from_jsdisp(jsdisp) : NULL;
 }
 
-static inline HRESULT enumvar_get_next_item(EnumeratorInstance *This)
+static inline HRESULT enumvar_get_next_item(EnumeratorInstance *This, script_ctx_t *ctx)
 {
     HRESULT hres;
     VARIANT nextitem;
@@ -60,7 +60,7 @@ static inline HRESULT enumvar_get_next_item(EnumeratorInstance *This)
     hres = IEnumVARIANT_Next(This->enumvar, 1, &nextitem, NULL);
     if (hres == S_OK)
     {
-        hres = variant_to_jsval(&nextitem, &This->item);
+        hres = variant_to_jsval(ctx, &nextitem, &This->item);
         VariantClear(&nextitem);
         if (FAILED(hres))
         {
@@ -134,7 +134,7 @@ static HRESULT Enumerator_moveFirst(script_ctx_t *ctx, jsval_t vthis, WORD flags
             return hres;
 
         This->atend = FALSE;
-        hres = enumvar_get_next_item(This);
+        hres = enumvar_get_next_item(This, ctx);
         if(FAILED(hres))
             return hres;
     }
@@ -157,7 +157,7 @@ static HRESULT Enumerator_moveNext(script_ctx_t *ctx, jsval_t vthis, WORD flags,
 
     if (This->enumvar)
     {
-        hres = enumvar_get_next_item(This);
+        hres = enumvar_get_next_item(This, ctx);
         if (FAILED(hres))
             return hres;
     }
@@ -272,7 +272,7 @@ static HRESULT create_enumerator(script_ctx_t *ctx, jsval_t *argv, jsdisp_t **re
 
     enumerator->enumvar = enumvar;
     enumerator->atend = !enumvar;
-    hres = enumvar_get_next_item(enumerator);
+    hres = enumvar_get_next_item(enumerator, ctx);
     if (FAILED(hres))
     {
         jsdisp_release(&enumerator->dispex);
diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c
index 7debf07..3251abf 100644
--- a/dlls/jscript/jsutils.c
+++ b/dlls/jscript/jsutils.c
@@ -244,7 +244,7 @@ HRESULT jsval_copy(jsval_t v, jsval_t *r)
     return E_FAIL;
 }
 
-HRESULT variant_to_jsval(VARIANT *var, jsval_t *r)
+HRESULT variant_to_jsval(script_ctx_t *ctx, VARIANT *var, jsval_t *r)
 {
     if(V_VT(var) == (VT_VARIANT|VT_BYREF))
         var = V_VARIANTREF(var);
@@ -281,7 +281,7 @@ HRESULT variant_to_jsval(VARIANT *var, jsval_t *r)
     }
     case VT_DISPATCH: {
         if(!V_DISPATCH(var)) {
-            *r = jsval_null_disp();
+            *r = ctx->html_mode ? jsval_null() : jsval_null_disp();
             return S_OK;
         }
         IDispatch_AddRef(V_DISPATCH(var));
@@ -333,7 +333,7 @@ HRESULT variant_to_jsval(VARIANT *var, jsval_t *r)
                 return S_OK;
             }
         }else {
-            *r = jsval_null_disp();
+            *r = ctx->html_mode ? jsval_null() : jsval_null_disp();
             return S_OK;
         }
         /* fall through */
@@ -882,7 +882,7 @@ HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTY
     jsval_t val;
     HRESULT hres;
 
-    hres = variant_to_jsval(src, &val);
+    hres = variant_to_jsval(ctx, src, &val);
     if(FAILED(hres))
         return hres;
 
diff --git a/dlls/jscript/jsval.h b/dlls/jscript/jsval.h
index 4e00d08..2517745 100644
--- a/dlls/jscript/jsval.h
+++ b/dlls/jscript/jsval.h
@@ -250,7 +250,7 @@ static inline BOOL get_bool(jsval_t v)
     return __JSVAL_BOOL(v);
 }
 
-HRESULT variant_to_jsval(VARIANT*,jsval_t*) DECLSPEC_HIDDEN;
+HRESULT variant_to_jsval(script_ctx_t*,VARIANT*,jsval_t*) DECLSPEC_HIDDEN;
 HRESULT jsval_to_variant(jsval_t,VARIANT*) DECLSPEC_HIDDEN;
 void jsval_release(jsval_t) DECLSPEC_HIDDEN;
 HRESULT jsval_copy(jsval_t,jsval_t*) DECLSPEC_HIDDEN;
diff --git a/dlls/jscript/vbarray.c b/dlls/jscript/vbarray.c
index 881c45e..987d714 100644
--- a/dlls/jscript/vbarray.c
+++ b/dlls/jscript/vbarray.c
@@ -93,7 +93,7 @@ static HRESULT VBArray_getItem(script_ctx_t *ctx, jsval_t vthis, WORD flags, uns
         return hres;
 
     if(r) {
-        hres = variant_to_jsval(&out, r);
+        hres = variant_to_jsval(ctx, &out, r);
         VariantClear(&out);
     }
     return hres;
@@ -163,7 +163,7 @@ static HRESULT VBArray_toArray(script_ctx_t *ctx, jsval_t vthis, WORD flags, uns
     }
 
     for(i=0; i<size; i++) {
-        hres = variant_to_jsval(v, &val);
+        hres = variant_to_jsval(ctx, v, &val);
         if(SUCCEEDED(hres)) {
             hres = jsdisp_propput_idx(array, i, val);
             jsval_release(val);
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js
index 5f475cc..28450f7 100644
--- a/dlls/mshtml/tests/documentmode.js
+++ b/dlls/mshtml/tests/documentmode.js
@@ -1325,7 +1325,6 @@ sync_test("builtins_diffs", function() {
 sync_test("nullDisp", function() {
     var v = document.documentMode, nullDisp = external.nullDisp, r;
 
-    todo_wine.
     ok(external.getVT(nullDisp) === "VT_NULL", "getVT(nullDisp) is not VT_NULL");
     ok(typeof(nullDisp) === "object", "typeof(nullDisp) = " + typeof(nullDisp));
     ok(nullDisp === nullDisp, "nullDisp !== nullDisp");
@@ -1342,10 +1341,11 @@ sync_test("nullDisp", function() {
     ok(r === "[object Object]", "Object(nullDisp).toString() = " + r);
     ok(Object(nullDisp) != nullDisp, "Object(nullDisp) == nullDisp");
     ok(new Object(nullDisp) != nullDisp, "new Object(nullDisp) == nullDisp");
+    r = (nullDisp instanceof Object);
+    ok(r === false, "nullDisp instance of Object");
 
     if(v >= 8) {
         r = JSON.stringify.call(null, nullDisp);
-        todo_wine.
         ok(r === "null", "JSON.stringify(nullDisp) returned " + r);
     }
 
@@ -1360,14 +1360,12 @@ sync_test("nullDisp", function() {
         Function.prototype.apply.call(nullDisp, Object, []);
         ok(false, "expected exception calling Function.apply on nullDisp");
     }catch(e) {
-        todo_wine.
         ok(e.number === 0xa138a - 0x80000000, "Function.apply on nullDisp threw " + e.number);
     }
     try {
         Function.prototype.call.call(nullDisp, Object);
         ok(false, "expected exception calling Function.call on nullDisp");
     }catch(e) {
-        todo_wine.
         ok(e.number === 0xa138a - 0x80000000, "Function.call on nullDisp threw " + e.number);
     }
 
@@ -1375,7 +1373,6 @@ sync_test("nullDisp", function() {
         new nullDisp;
         ok(false, "expected exception for new nullDisp");
     }catch(e) {
-        todo_wine.
         ok(e.number === 0xa138f - 0x80000000, "new nullDisp threw " + e.number);
     }
 });
diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js
index 14ec4f9..e8ee713 100644
--- a/dlls/mshtml/tests/es5.js
+++ b/dlls/mshtml/tests/es5.js
@@ -1362,6 +1362,7 @@ sync_test("isFrozen", function() {
 });
 
 sync_test("builtin_context", function() {
+    var nullDisp = external.nullDisp;
     var tests = [
         [ "Array.map",              JS_E_OBJECT_EXPECTED,       function(ctx) { Array.prototype.map.call(ctx, function(a, b) {}); } ],
         [ "Array.sort",             JS_E_OBJECT_EXPECTED,       function(ctx) { Array.prototype.sort.call(ctx); } ],
@@ -1400,6 +1401,13 @@ sync_test("builtin_context", function() {
             var n = ex.number >>> 0;
             ok(n === tests[i][1], tests[i][0] + " with undefined context exception code = " + n);
         }
+        try {
+            tests[i][2](nullDisp);
+            ok(false, "expected exception calling " + tests[i][0] + " with nullDisp context");
+        }catch(ex) {
+            var n = ex.number >>> 0;
+            ok(n === tests[i][1], tests[i][0] + " with nullDisp context exception code = " + n);
+        }
     }
 
     var obj = (function() { return this; }).call(null);
-- 
2.34.1




More information about the wine-devel mailing list