Explorar o código

LibJS: Don't coerce this value to object in Promise.resolve()

Linus Groh %!s(int64=3) %!d(string=hai) anos
pai
achega
53ec432e8d

+ 5 - 3
Userland/Libraries/LibJS/Runtime/PromiseConstructor.cpp

@@ -519,12 +519,14 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::resolve)
     auto value = vm.argument(0);
     auto value = vm.argument(0);
 
 
     // 1. Let C be the this value.
     // 1. Let C be the this value.
+    auto constructor = vm.this_value(global_object);
+
     // 2. If Type(C) is not Object, throw a TypeError exception.
     // 2. If Type(C) is not Object, throw a TypeError exception.
-    // FIXME: Don't coerce to object!
-    auto* constructor = TRY(vm.this_value(global_object).to_object(global_object));
+    if (!constructor.is_object())
+        return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, constructor.to_string_without_side_effects());
 
 
     // 3. Return ? PromiseResolve(C, x).
     // 3. Return ? PromiseResolve(C, x).
-    return TRY(promise_resolve(global_object, *constructor, value));
+    return TRY(promise_resolve(global_object, constructor.as_object(), value));
 }
 }
 
 
 // 27.2.4.8 get Promise [ @@species ], https://tc39.es/ecma262/#sec-get-promise-@@species
 // 27.2.4.8 get Promise [ @@species ], https://tc39.es/ecma262/#sec-get-promise-@@species

+ 8 - 0
Userland/Libraries/LibJS/Tests/builtins/Promise/Promise.resolve.js

@@ -31,3 +31,11 @@ describe("normal behavior", () => {
         expect(fulfillmentValue).toBe("Some value");
         expect(fulfillmentValue).toBe("Some value");
     });
     });
 });
 });
+
+describe("errors", () => {
+    test("this value must be an object", () => {
+        expect(() => {
+            Promise.resolve.call("foo");
+        }).toThrowWithMessage(TypeError, "foo is not an object");
+    });
+});