Fix correctness issue in proxy set trap

According to the spec, in case where the property is non-configurable and
non-writable, the value passed to the set trap should be compared to the data.
Instead, the trap result was compared, because of the misleading name of the
CheckGetSetTrapResult parameter.

Regression was introduced in
https://chromium-review.googlesource.com/c/v8/v8/+/1604071

Bug: chromium:966450
Change-Id: I77501980475da3aeb4f6153321da39e6fc2e6bd9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1632238
Auto-Submit: Maya Lekova <mslekova@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61916}
This commit is contained in:
Maya Lekova 2019-05-28 17:44:18 +02:00 committed by Commit Bot
parent dadab3c483
commit 731a370b1f
3 changed files with 19 additions and 2 deletions

View File

@ -265,6 +265,7 @@ TF_BUILTIN(ConstructProxy, ProxiesCodeStubAssembler) {
Node* ProxiesCodeStubAssembler::CheckGetSetTrapResult(
Node* context, Node* target, Node* proxy, Node* name, Node* trap_result,
JSProxy::AccessKind access_kind) {
// TODO(mslekova): Think of a better name for the trap_result param.
Node* map = LoadMap(target);
VARIABLE(var_value, MachineRepresentation::kTagged);
VARIABLE(var_details, MachineRepresentation::kWord32);

View File

@ -64,8 +64,7 @@ namespace proxy {
const trapResult = Call(
context, trap, handlerJSReceiver, target, name, value, receiverValue);
if (BranchIfToBooleanIsTrue(trapResult)) {
return CheckGetSetTrapResult(
target, proxy, name, trapResult, kProxySet);
return CheckGetSetTrapResult(target, proxy, name, value, kProxySet);
}
ThrowTypeErrorIfStrict(
SmiConstant(kProxyTrapReturnedFalsishFor), 'set', name);

View File

@ -0,0 +1,17 @@
// Copyright 2019 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.
let prop = "someName";
function foo(a, b, v) { return a[b] = 0 }
try {
foo("", prop);
} catch(e) {}
var target = {};
var traps = { set() {return 42} };
var proxy = new Proxy(target, traps);
Object.defineProperty(target, prop, { value: 0 });
try {
foo(proxy, prop);
} catch (e) { }
foo(proxy, prop, 0);