From 172bfb58345f9eefd804714f787cf2c4981b2eab Mon Sep 17 00:00:00 2001 From: cbruni Date: Fri, 5 Aug 2016 05:52:02 -0700 Subject: [PATCH] [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} --- src/elements.cc | 16 ++++++++++------ src/elements.h | 4 ++-- src/keys.cc | 21 ++++++++++++--------- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/elements.cc b/src/elements.cc index b10e1f7f1b..29fa4fb08c 100644 --- a/src/elements.cc +++ b/src/elements.cc @@ -1030,16 +1030,15 @@ class ElementsAccessorBase : public ElementsAccessor { return list; } - Handle PrependElementIndices(Handle object, - Handle backing_store, - Handle keys, - GetKeysConversion convert, - PropertyFilter filter) final { + MaybeHandle PrependElementIndices( + Handle object, Handle backing_store, + Handle keys, GetKeysConversion convert, + PropertyFilter filter) final { return Subclass::PrependElementIndicesImpl(object, backing_store, keys, convert, filter); } - static Handle PrependElementIndicesImpl( + static MaybeHandle PrependElementIndicesImpl( Handle object, Handle backing_store, Handle 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(isolate->factory()->NewRangeError( + MessageTemplate::kInvalidArrayLength)); + } bool needs_sorting = IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind()); diff --git a/src/elements.h b/src/elements.h index a2fb0352ca..f4b0b0b7c5 100644 --- a/src/elements.h +++ b/src/elements.h @@ -94,12 +94,12 @@ class ElementsAccessor { Handle values_or_entries, bool get_entries, int* nof_items, PropertyFilter filter = ALL_PROPERTIES) = 0; - virtual Handle PrependElementIndices( + virtual MaybeHandle PrependElementIndices( Handle object, Handle backing_store, Handle keys, GetKeysConversion convert, PropertyFilter filter = ALL_PROPERTIES) = 0; - inline Handle PrependElementIndices( + inline MaybeHandle PrependElementIndices( Handle object, Handle keys, GetKeysConversion convert, PropertyFilter filter = ALL_PROPERTIES) { return PrependElementIndices(object, handle(object->elements()), keys, diff --git a/src/keys.cc b/src/keys.cc index 81e2696cda..c6e31e3f23 100644 --- a/src/keys.cc +++ b/src/keys.cc @@ -348,9 +348,9 @@ Handle GetFastEnumPropertyKeys(Isolate* isolate, } template -Handle GetOwnKeysWithElements(Isolate* isolate, - Handle object, - GetKeysConversion convert) { +MaybeHandle GetOwnKeysWithElements(Isolate* isolate, + Handle object, + GetKeysConversion convert) { Handle keys; ElementsAccessor* accessor = object->GetElementsAccessor(); if (fast_properties) { @@ -359,12 +359,12 @@ Handle GetOwnKeysWithElements(Isolate* isolate, // TODO(cbruni): preallocate big enough array to also hold elements. keys = KeyAccumulator::GetOwnEnumPropertyKeys(isolate, object); } - Handle result = + MaybeHandle 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 FastKeyAccumulator::GetKeys( GetKeysConversion keys_conversion) { - Handle keys; - if (filter_ == ENUMERABLE_STRINGS && - GetKeysFast(keys_conversion).ToHandle(&keys)) { - return keys; + if (filter_ == ENUMERABLE_STRINGS) { + Handle keys; + if (GetKeysFast(keys_conversion).ToHandle(&keys)) { + return keys; + } + if (isolate_->has_pending_exception()) return MaybeHandle(); } + return GetKeysSlow(keys_conversion); }