Commit 39c3a97e authored by jameslahm's avatar jameslahm Committed by V8 LUCI CQ

[builtin] Throw type error when HasAccessCheckFailed in PromiseConstructor.

When cross realm invoke PromiseConstructor and realm not
allowed to CrossRealmAccess, PromiseConstructor will
silently return undefined, which will cause crash in
ConstructJSWithTarget type cast, Change to throw type
error when HasAccessCheck failed.

Bug: v8:12705
Change-Id: I18f697a1897c31163dd60522db12449033419f9a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3521174Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79548}
parent bba8bc2b
...@@ -60,11 +60,11 @@ PromiseConstructor( ...@@ -60,11 +60,11 @@ PromiseConstructor(
const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX); const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX);
// Silently fail if the stack looks fishy. // Throw no access type error if the stack looks fishy.
if (HasAccessCheckFailed(context, promiseFun, executor)) { if (HasAccessCheckFailed(context, promiseFun, executor)) {
IncrementUseCounter( IncrementUseCounter(
context, SmiConstant(kPromiseConstructorReturnedUndefined)); context, SmiConstant(kPromiseConstructorReturnedUndefined));
return Undefined; runtime::ThrowNoAccess();
} }
let result: JSPromise; let result: JSPromise;
......
...@@ -9,6 +9,8 @@ namespace runtime { ...@@ -9,6 +9,8 @@ namespace runtime {
extern transitioning runtime extern transitioning runtime
AllowDynamicFunction(implicit context: Context)(JSAny): JSAny; AllowDynamicFunction(implicit context: Context)(JSAny): JSAny;
extern transitioning runtime ThrowNoAccess(implicit context: Context)(): never;
extern transitioning runtime extern transitioning runtime
ReportMessageFromMicrotask(implicit context: Context)(JSAny): JSAny; ReportMessageFromMicrotask(implicit context: Context)(JSAny): JSAny;
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <memory> #include <memory>
#include "src/api/api-inl.h"
#include "src/api/api.h" #include "src/api/api.h"
#include "src/ast/ast-traversal-visitor.h" #include "src/ast/ast-traversal-visitor.h"
#include "src/ast/prettyprinter.h" #include "src/ast/prettyprinter.h"
...@@ -296,6 +297,19 @@ RUNTIME_FUNCTION(Runtime_ThrowSymbolIteratorInvalid) { ...@@ -296,6 +297,19 @@ RUNTIME_FUNCTION(Runtime_ThrowSymbolIteratorInvalid) {
isolate, NewTypeError(MessageTemplate::kSymbolIteratorInvalid)); isolate, NewTypeError(MessageTemplate::kSymbolIteratorInvalid));
} }
RUNTIME_FUNCTION(Runtime_ThrowNoAccess) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
// TODO(verwaest): We would like to throw using the calling context instead
// of the entered context but we don't currently have access to that.
HandleScopeImplementer* impl = isolate->handle_scope_implementer();
SaveAndSwitchContext save(
isolate, impl->LastEnteredOrMicrotaskContext()->native_context());
THROW_NEW_ERROR_RETURN_FAILURE(isolate,
NewTypeError(MessageTemplate::kNoAccess));
}
RUNTIME_FUNCTION(Runtime_ThrowNotConstructor) { RUNTIME_FUNCTION(Runtime_ThrowNotConstructor) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK_EQ(1, args.length()); DCHECK_EQ(1, args.length());
......
...@@ -252,6 +252,7 @@ namespace internal { ...@@ -252,6 +252,7 @@ namespace internal {
F(ThrowIteratorError, 1, 1) \ F(ThrowIteratorError, 1, 1) \
F(ThrowSpreadArgError, 2, 1) \ F(ThrowSpreadArgError, 2, 1) \
F(ThrowIteratorResultNotAnObject, 1, 1) \ F(ThrowIteratorResultNotAnObject, 1, 1) \
F(ThrowNoAccess, 0, 1) \
F(ThrowNotConstructor, 1, 1) \ F(ThrowNotConstructor, 1, 1) \
F(ThrowPatternAssignmentNonCoercible, 1, 1) \ F(ThrowPatternAssignmentNonCoercible, 1, 1) \
F(ThrowRangeError, -1 /* >= 1 */, 1) \ F(ThrowRangeError, -1 /* >= 1 */, 1) \
......
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const r = Realm.create();
const otherPromise = Realm.eval(r, 'Promise.resolve()');
assertThrows(
() => {
Promise.prototype.then.call(otherPromise, () => { });
}, TypeError, 'no access');
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment