Handle failure in KeyAccumulator::GetKeys

It turns out that KeyAccumulator::GetKeys will fail if the object it is
operating on is a Proxy with an ownKeys() or getOwnPropertyDescriptor()
trap that throws. Handle this case in
Isolate::GetImportAssertionsFromArgument by bailing out early.

Bug: v8:11730
Change-Id: I363bf2d218f6ba7eeb2001cd644f5529901fdb3e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2875541
Reviewed-by: Adam Klein <adamk@chromium.org>
Reviewed-by: Marja Hölttä <marja@chromium.org>
Commit-Queue: Dan Clark <daniec@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#74417}
This commit is contained in:
Daniel Clark 2021-05-06 07:57:12 -07:00 committed by V8 LUCI CQ
parent 6b6c87e53a
commit 95f72de8ca
2 changed files with 35 additions and 5 deletions

View File

@ -4328,11 +4328,15 @@ MaybeHandle<FixedArray> Isolate::GetImportAssertionsFromArgument(
Handle<JSReceiver> import_assertions_object_receiver =
Handle<JSReceiver>::cast(import_assertions_object);
Handle<FixedArray> assertion_keys =
KeyAccumulator::GetKeys(import_assertions_object_receiver,
Handle<FixedArray> assertion_keys;
if (!KeyAccumulator::GetKeys(import_assertions_object_receiver,
KeyCollectionMode::kOwnOnly, ENUMERABLE_STRINGS,
GetKeysConversion::kConvertToString)
.ToHandleChecked();
.ToHandle(&assertion_keys)) {
// This happens if the assertions object is a Proxy whose ownKeys() or
// getOwnPropertyDescriptor() trap throws.
return MaybeHandle<FixedArray>();
}
// The assertions will be passed to the host in the form: [key1,
// value1, key2, value2, ...].

View File

@ -0,0 +1,26 @@
// Copyright 2021 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.
// Flags: --allow-natives-syntax --harmony-import-assertions
let result1;
let result2;
let badAssertProxy1 = new Proxy({}, { ownKeys() { throw "bad ownKeys!"; } });
import('./modules-skip-1.mjs', { assert: badAssertProxy1 }).then(
() => assertUnreachable('Should have failed due to throwing ownKeys'),
error => result1 = error);
let badAssertProxy2 = new Proxy(
{foo: "bar"},
{ getOwnPropertyDescriptor() { throw "bad getOwnPropertyDescriptor!"; } });
import('./modules-skip-1.mjs', { assert: badAssertProxy2 }).then(
() => assertUnreachable(
'Should have failed due to throwing getOwnPropertyDescriptor'),
error => result2 = error);
%PerformMicrotaskCheckpoint();
assertEquals('bad ownKeys!', result1);
assertEquals('bad getOwnPropertyDescriptor!', result2);