[PATCH 2/2] jscript: Set detached scope objects 'this' to undefined in ES5 mode.

Gabriel Ivăncescu gabrielopcode at gmail.com
Wed May 4 11:10:49 CDT 2022


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/jscript/function.c  | 18 ++++++++++++++++--
 dlls/mshtml/tests/es5.js | 15 +++++++++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
index 12511bb..d82482c 100644
--- a/dlls/jscript/function.c
+++ b/dlls/jscript/function.c
@@ -247,16 +247,30 @@ void detach_arguments_object(jsdisp_t *args_disp)
     jsdisp_release(frame->arguments_obj);
 }
 
+/* ECMA-262 5.1 Edition    11.2.3.6 */
+static jsval_t setup_this(script_ctx_t *ctx, jsval_t vthis)
+{
+    jsdisp_t *jsdisp;
+
+    if(ctx->version < SCRIPTLANGUAGEVERSION_ES5)
+        return vthis;
+    if(is_object_instance(vthis) && (jsdisp = to_jsdisp(get_object(vthis))) && jsdisp->builtin_info->class == JSCLASS_NONE)
+        return jsval_undefined();
+    return vthis;
+}
+
 HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     FunctionInstance *function;
+    jsval_t vthis;
 
     TRACE("func %p this %p\n", func_this, jsthis);
 
     assert(is_class(func_this, JSCLASS_FUNCTION));
     function = function_from_jsdisp(func_this);
 
-    return function->vtbl->call(function->dispex.ctx, function, jsthis ? jsval_disp(jsthis) : jsval_null(), flags, argc, argv, r);
+    vthis = setup_this(function->dispex.ctx, jsthis ? jsval_disp(jsthis) : jsval_null());
+    return function->vtbl->call(function->dispex.ctx, function, vthis, flags, argc, argv, r);
 }
 
 static HRESULT Function_get_length(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
@@ -483,7 +497,7 @@ HRESULT Function_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned ar
         return E_FAIL;
     }
 
-    return function->vtbl->call(ctx, function, vthis, flags, argc, argv, r);
+    return function->vtbl->call(ctx, function, setup_this(ctx, vthis), flags, argc, argv, r);
 }
 
 HRESULT Function_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js
index 8238e5d..fb756ac 100644
--- a/dlls/mshtml/tests/es5.js
+++ b/dlls/mshtml/tests/es5.js
@@ -1784,6 +1784,21 @@ sync_test("let scope instances", function() {
     ok(f() == 2, "f() = " + f());
 });
 
+sync_test("builtins detached scope this", function() {
+    try {
+        ((function() { var f = Number.prototype.toString; return (function() { return f(); }); })())();
+    }catch(ex) {
+        var n = ex.number >>> 0;
+        ok(n === JS_E_NUMBER_EXPECTED, "Number.toString threw " + n);
+    }
+
+    var r = ((function() { var f = Object.prototype.toString; return (function() { return f(); }); })())();
+    ok(r === "[object Undefined]", "Object.toString returned " + r);
+
+    var r = ((function() { return (function() { return this; }); })())();
+    ok(r === window, "detached scope this = " + r);
+});
+
 sync_test("functions scope", function() {
     function f(){ return 1; }
     function f(){ return 2; }
-- 
2.34.1




More information about the wine-devel mailing list