Index: src/prototype.h |
diff --git a/src/prototype.h b/src/prototype.h |
index ea3495569ee9b6be0364137fe59859f726323edb..ad3d59d7770d98bc0a293afbb37e46a546f56f8b 100644 |
--- a/src/prototype.h |
+++ b/src/prototype.h |
@@ -28,12 +28,15 @@ class PrototypeIterator { |
enum WhereToEnd { END_AT_NULL, END_AT_NON_HIDDEN }; |
+ const int kProxyPrototypeLimit = 100 * 1000; |
+ |
PrototypeIterator(Isolate* isolate, Handle<Object> receiver, |
WhereToStart where_to_start = START_AT_PROTOTYPE) |
: did_jump_to_prototype_chain_(false), |
object_(NULL), |
handle_(receiver), |
- isolate_(isolate) { |
+ isolate_(isolate), |
+ seen_proxies_(0) { |
CHECK(!handle_.is_null()); |
if (where_to_start == START_AT_PROTOTYPE) { |
Advance(); |
@@ -44,7 +47,8 @@ class PrototypeIterator { |
WhereToStart where_to_start = START_AT_PROTOTYPE) |
: did_jump_to_prototype_chain_(false), |
object_(receiver), |
- isolate_(isolate) { |
+ isolate_(isolate), |
+ seen_proxies_(0) { |
if (where_to_start == START_AT_PROTOTYPE) { |
Advance(); |
} |
@@ -127,14 +131,22 @@ class PrototypeIterator { |
handle_ = isolate_->factory()->null_value(); |
return true; |
} |
- if (!handle_.is_null() && handle_->IsJSProxy()) { |
- did_jump_to_prototype_chain_ = true; |
- MaybeHandle<Object> proto = |
- JSProxy::GetPrototype(Handle<JSProxy>::cast(handle_)); |
- return proto.ToHandle(&handle_); |
+ if (handle_.is_null() || !handle_->IsJSProxy()) { |
+ AdvanceIgnoringProxies(); |
+ return true; |
} |
- AdvanceIgnoringProxies(); |
- return true; |
+ // Due to possible __proto__ recursion limit the number of Proxies |
+ // we visit to an arbitrarily chosen large number. |
+ seen_proxies_++; |
+ if (seen_proxies_ > kProxyPrototypeLimit) { |
+ isolate_->Throw( |
+ *isolate_->factory()->NewRangeError(MessageTemplate::kStackOverflow)); |
+ return false; |
+ } |
+ did_jump_to_prototype_chain_ = true; |
+ MaybeHandle<Object> proto = |
+ JSProxy::GetPrototype(Handle<JSProxy>::cast(handle_)); |
+ return proto.ToHandle(&handle_); |
} |
bool IsAtEnd(WhereToEnd where_to_end = END_AT_NULL) const { |
@@ -166,6 +178,7 @@ class PrototypeIterator { |
Object* object_; |
Handle<Object> handle_; |
Isolate* isolate_; |
+ int seen_proxies_; |
DISALLOW_COPY_AND_ASSIGN(PrototypeIterator); |
}; |