From a305d6d218663487d603389218ae87cefd6a7ae0 Mon Sep 17 00:00:00 2001 From: Charlie Gordon Date: Wed, 13 Mar 2024 20:34:55 +0100 Subject: [PATCH 1/2] Make `Object.prototype` an immutable prototype object --- quickjs.c | 4 ++++ tests/test_builtin.js | 2 ++ 2 files changed, 6 insertions(+) diff --git a/quickjs.c b/quickjs.c index bcb962a72..196a8c91f 100644 --- a/quickjs.c +++ b/quickjs.c @@ -6859,6 +6859,10 @@ static int JS_SetPrototypeInternal(JSContext *ctx, JSValue obj, sh = p->shape; if (sh->proto == proto) return TRUE; + if (p == JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_OBJECT])) { + JS_ThrowTypeError(ctx, "'Immutable prototype object \'Object.prototype\' cannot have their prototype set'"); + return -1; + } if (!p->extensible) { if (throw_flag) { JS_ThrowTypeError(ctx, "object is not extensible"); diff --git a/tests/test_builtin.js b/tests/test_builtin.js index 98faa748f..542095174 100644 --- a/tests/test_builtin.js +++ b/tests/test_builtin.js @@ -220,6 +220,8 @@ function test() assert(Object.isExtensible(a), false, "extensible"); assert(typeof a.y, "undefined", "extensible"); assert(err, true, "extensible"); + + assert_throws(TypeError, () => Object.setPrototypeOf(Object.prototype, {})); } function test_enum() From 84fc8910c8abdd970279b7368f3b0168d2102ffe Mon Sep 17 00:00:00 2001 From: Charlie Gordon Date: Wed, 13 Mar 2024 22:00:52 +0100 Subject: [PATCH 2/2] Unbreak test262 Do not throw an exception for `Reflect.setPrototypeOf(Object.prototype, xxx)` --- quickjs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/quickjs.c b/quickjs.c index 196a8c91f..e1ec8c340 100644 --- a/quickjs.c +++ b/quickjs.c @@ -6860,8 +6860,11 @@ static int JS_SetPrototypeInternal(JSContext *ctx, JSValue obj, if (sh->proto == proto) return TRUE; if (p == JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_OBJECT])) { - JS_ThrowTypeError(ctx, "'Immutable prototype object \'Object.prototype\' cannot have their prototype set'"); - return -1; + if (throw_flag) { + JS_ThrowTypeError(ctx, "'Immutable prototype object \'Object.prototype\' cannot have their prototype set'"); + return -1; + } + return FALSE; } if (!p->extensible) { if (throw_flag) {