[builtins] Fix FastCreateDataProperty
... which didn't check writability of array length on appending a new element to an array. Bug: chromium:1041251 Change-Id: I6935e505a4844e5b22abe9d4a42786619499daa6 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2023551 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/master@{#66023}
This commit is contained in:
parent
390c7fed66
commit
68cc5c6796
@ -1439,36 +1439,44 @@ transitioning builtin FastCreateDataProperty(implicit context: Context)(
|
||||
const array = Cast<FastJSArray>(receiver) otherwise Slow;
|
||||
const index: Smi = Cast<Smi>(key) otherwise goto Slow;
|
||||
if (index < 0 || index > array.length) goto Slow;
|
||||
array::EnsureWriteableFastElements(array);
|
||||
const isAppend = index == array.length;
|
||||
const kind = array.map.elements_kind;
|
||||
// We may have to transition a.
|
||||
// For now, if transition is required, jump away to slow.
|
||||
if (IsFastSmiElementsKind(kind)) {
|
||||
const smiValue = Cast<Smi>(value) otherwise Slow;
|
||||
if (isAppend) {
|
||||
|
||||
if (isAppend) {
|
||||
// Fast append only works on fast elements kind and with writable length.
|
||||
const kind = EnsureArrayPushable(array.map) otherwise Slow;
|
||||
array::EnsureWriteableFastElements(array);
|
||||
|
||||
// We may have to transition a.
|
||||
// For now, if transition is required, jump away to slow.
|
||||
if (IsFastSmiElementsKind(kind)) {
|
||||
BuildAppendJSArray(ElementsKind::HOLEY_SMI_ELEMENTS, array, value)
|
||||
otherwise Slow;
|
||||
} else {
|
||||
const elements = Cast<FixedArray>(array.elements) otherwise unreachable;
|
||||
elements[index] = smiValue;
|
||||
}
|
||||
} else if (IsDoubleElementsKind(kind)) {
|
||||
const numberValue = Cast<Number>(value) otherwise Slow;
|
||||
if (isAppend) {
|
||||
} else if (IsDoubleElementsKind(kind)) {
|
||||
BuildAppendJSArray(ElementsKind::HOLEY_DOUBLE_ELEMENTS, array, value)
|
||||
otherwise Slow;
|
||||
} else {
|
||||
assert(IsFastSmiOrTaggedElementsKind(kind));
|
||||
BuildAppendJSArray(ElementsKind::HOLEY_ELEMENTS, array, value)
|
||||
otherwise Slow;
|
||||
}
|
||||
} else {
|
||||
// Non-appending element store.
|
||||
const kind = array.map.elements_kind;
|
||||
array::EnsureWriteableFastElements(array);
|
||||
|
||||
// We may have to transition a.
|
||||
// For now, if transition is required, jump away to slow.
|
||||
if (IsFastSmiElementsKind(kind)) {
|
||||
const smiValue = Cast<Smi>(value) otherwise Slow;
|
||||
const elements = Cast<FixedArray>(array.elements) otherwise unreachable;
|
||||
elements[index] = smiValue;
|
||||
} else if (IsDoubleElementsKind(kind)) {
|
||||
const numberValue = Cast<Number>(value) otherwise Slow;
|
||||
const doubleElements = Cast<FixedDoubleArray>(array.elements)
|
||||
otherwise unreachable;
|
||||
doubleElements[index] = numberValue;
|
||||
}
|
||||
} else {
|
||||
assert(IsFastSmiOrTaggedElementsKind(kind));
|
||||
if (isAppend) {
|
||||
BuildAppendJSArray(ElementsKind::HOLEY_ELEMENTS, array, value)
|
||||
otherwise Slow;
|
||||
} else {
|
||||
assert(IsFastSmiOrTaggedElementsKind(kind));
|
||||
const elements = Cast<FixedArray>(array.elements) otherwise unreachable;
|
||||
elements[index] = value;
|
||||
}
|
||||
|
14
test/mjsunit/regress/regress-crbug-1041251.js
Normal file
14
test/mjsunit/regress/regress-crbug-1041251.js
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2020 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 v0 = [0, 1];
|
||||
v0.constructor = {
|
||||
[Symbol.species]: function() {
|
||||
let v1 = [2];
|
||||
Object.defineProperty(v1, "length", {writable: false});
|
||||
return v1;
|
||||
}
|
||||
}
|
||||
|
||||
assertThrows(() => Array.prototype.map.call(v0, function() {}), TypeError);
|
Loading…
Reference in New Issue
Block a user