[keys] Throw a range error if the number of keys overflow FixedArray::kMaxLength

BUG=chromium:634776

Review-Url: https://codereview.chromium.org/2219803002
Cr-Commit-Position: refs/heads/master@{#38382}
This commit is contained in:
cbruni 2016-08-05 05:52:02 -07:00 committed by Commit bot
parent 55a4344f41
commit 172bfb5834
3 changed files with 24 additions and 17 deletions

View File

@ -1030,16 +1030,15 @@ class ElementsAccessorBase : public ElementsAccessor {
return list;
}
Handle<FixedArray> PrependElementIndices(Handle<JSObject> object,
Handle<FixedArrayBase> backing_store,
Handle<FixedArray> keys,
GetKeysConversion convert,
MaybeHandle<FixedArray> PrependElementIndices(
Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
Handle<FixedArray> keys, GetKeysConversion convert,
PropertyFilter filter) final {
return Subclass::PrependElementIndicesImpl(object, backing_store, keys,
convert, filter);
}
static Handle<FixedArray> PrependElementIndicesImpl(
static MaybeHandle<FixedArray> PrependElementIndicesImpl(
Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
Handle<FixedArray> keys, GetKeysConversion convert,
PropertyFilter filter) {
@ -1048,6 +1047,11 @@ class ElementsAccessorBase : public ElementsAccessor {
uint32_t initial_list_length =
Subclass::GetMaxNumberOfEntries(*object, *backing_store);
initial_list_length += nof_property_keys;
if (initial_list_length > FixedArray::kMaxLength ||
initial_list_length < nof_property_keys) {
return isolate->Throw<FixedArray>(isolate->factory()->NewRangeError(
MessageTemplate::kInvalidArrayLength));
}
bool needs_sorting =
IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind());

View File

@ -94,12 +94,12 @@ class ElementsAccessor {
Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items,
PropertyFilter filter = ALL_PROPERTIES) = 0;
virtual Handle<FixedArray> PrependElementIndices(
virtual MaybeHandle<FixedArray> PrependElementIndices(
Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
Handle<FixedArray> keys, GetKeysConversion convert,
PropertyFilter filter = ALL_PROPERTIES) = 0;
inline Handle<FixedArray> PrependElementIndices(
inline MaybeHandle<FixedArray> PrependElementIndices(
Handle<JSObject> object, Handle<FixedArray> keys,
GetKeysConversion convert, PropertyFilter filter = ALL_PROPERTIES) {
return PrependElementIndices(object, handle(object->elements()), keys,

View File

@ -348,7 +348,7 @@ Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate,
}
template <bool fast_properties>
Handle<FixedArray> GetOwnKeysWithElements(Isolate* isolate,
MaybeHandle<FixedArray> GetOwnKeysWithElements(Isolate* isolate,
Handle<JSObject> object,
GetKeysConversion convert) {
Handle<FixedArray> keys;
@ -359,12 +359,12 @@ Handle<FixedArray> GetOwnKeysWithElements(Isolate* isolate,
// TODO(cbruni): preallocate big enough array to also hold elements.
keys = KeyAccumulator::GetOwnEnumPropertyKeys(isolate, object);
}
Handle<FixedArray> result =
MaybeHandle<FixedArray> result =
accessor->PrependElementIndices(object, keys, convert, ONLY_ENUMERABLE);
if (FLAG_trace_for_in_enumerate) {
PrintF("| strings=%d symbols=0 elements=%u || prototypes>=1 ||\n",
keys->length(), result->length() - keys->length());
keys->length(), result.ToHandleChecked()->length() - keys->length());
}
return result;
}
@ -396,11 +396,14 @@ bool OnlyHasSimpleProperties(Map* map) {
MaybeHandle<FixedArray> FastKeyAccumulator::GetKeys(
GetKeysConversion keys_conversion) {
if (filter_ == ENUMERABLE_STRINGS) {
Handle<FixedArray> keys;
if (filter_ == ENUMERABLE_STRINGS &&
GetKeysFast(keys_conversion).ToHandle(&keys)) {
if (GetKeysFast(keys_conversion).ToHandle(&keys)) {
return keys;
}
if (isolate_->has_pending_exception()) return MaybeHandle<FixedArray>();
}
return GetKeysSlow(keys_conversion);
}