[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; return list;
} }
Handle<FixedArray> PrependElementIndices(Handle<JSObject> object, MaybeHandle<FixedArray> PrependElementIndices(
Handle<FixedArrayBase> backing_store, Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
Handle<FixedArray> keys, Handle<FixedArray> keys, GetKeysConversion convert,
GetKeysConversion convert,
PropertyFilter filter) final { PropertyFilter filter) final {
return Subclass::PrependElementIndicesImpl(object, backing_store, keys, return Subclass::PrependElementIndicesImpl(object, backing_store, keys,
convert, filter); convert, filter);
} }
static Handle<FixedArray> PrependElementIndicesImpl( static MaybeHandle<FixedArray> PrependElementIndicesImpl(
Handle<JSObject> object, Handle<FixedArrayBase> backing_store, Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
Handle<FixedArray> keys, GetKeysConversion convert, Handle<FixedArray> keys, GetKeysConversion convert,
PropertyFilter filter) { PropertyFilter filter) {
@ -1048,6 +1047,11 @@ class ElementsAccessorBase : public ElementsAccessor {
uint32_t initial_list_length = uint32_t initial_list_length =
Subclass::GetMaxNumberOfEntries(*object, *backing_store); Subclass::GetMaxNumberOfEntries(*object, *backing_store);
initial_list_length += nof_property_keys; 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 = bool needs_sorting =
IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind()); IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind());

View File

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

View File

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