Commit ea6b9609 authored by jgruber's avatar jgruber Committed by Commit bot

Handle stack overflows in NoSideEffectToString

An infinite recursion can be triggered when NoSideEffectToString is
called on an error object with its name property set to itself.

BUG=633998

Review-Url: https://codereview.chromium.org/2206313002
Cr-Commit-Position: refs/heads/master@{#38325}
parent a53d4687
...@@ -228,21 +228,22 @@ bool IsErrorObject(Isolate* isolate, Handle<Object> object) { ...@@ -228,21 +228,22 @@ bool IsErrorObject(Isolate* isolate, Handle<Object> object) {
.FromMaybe(false); .FromMaybe(false);
} }
Handle<String> AsStringOrEmpty(Isolate* isolate, Handle<Object> object) {
return object->IsString() ? Handle<String>::cast(object)
: isolate->factory()->empty_string();
}
Handle<String> NoSideEffectsErrorToString(Isolate* isolate, Handle<String> NoSideEffectsErrorToString(Isolate* isolate,
Handle<Object> input) { Handle<Object> input) {
Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(input); Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(input);
Handle<Name> name_key = isolate->factory()->name_string(); Handle<Name> name_key = isolate->factory()->name_string();
Handle<Object> name = JSReceiver::GetDataProperty(receiver, name_key); Handle<Object> name = JSReceiver::GetDataProperty(receiver, name_key);
Handle<String> name_str = (name->IsUndefined(isolate)) Handle<String> name_str = AsStringOrEmpty(isolate, name);
? isolate->factory()->Error_string()
: Object::NoSideEffectsToString(isolate, name);
Handle<Name> msg_key = isolate->factory()->message_string(); Handle<Name> msg_key = isolate->factory()->message_string();
Handle<Object> msg = JSReceiver::GetDataProperty(receiver, msg_key); Handle<Object> msg = JSReceiver::GetDataProperty(receiver, msg_key);
Handle<String> msg_str = (msg->IsUndefined(isolate)) Handle<String> msg_str = AsStringOrEmpty(isolate, msg);
? isolate->factory()->empty_string()
: Object::NoSideEffectsToString(isolate, msg);
if (name_str->length() == 0) return msg_str; if (name_str->length() == 0) return msg_str;
if (msg_str->length() == 0) return name_str; if (msg_str->length() == 0) return name_str;
...@@ -321,7 +322,7 @@ Handle<String> Object::NoSideEffectsToString(Isolate* isolate, ...@@ -321,7 +322,7 @@ Handle<String> Object::NoSideEffectsToString(Isolate* isolate,
} else if (ctor->IsJSFunction()) { } else if (ctor->IsJSFunction()) {
Handle<Object> ctor_name_obj = Handle<Object> ctor_name_obj =
JSFunction::GetName(isolate, Handle<JSFunction>::cast(ctor)); JSFunction::GetName(isolate, Handle<JSFunction>::cast(ctor));
ctor_name = NoSideEffectsToString(isolate, ctor_name_obj); ctor_name = AsStringOrEmpty(isolate, ctor_name_obj);
} }
if (ctor_name->length() != 0) { if (ctor_name->length() != 0) {
......
// Copyright 2015 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.
var err_str_1 = "apply was called on , which is a object and not a function";
var err_str_2 =
"apply was called on Error, which is a object and not a function";
var reached = false;
var error = new Error();
error.name = error;
try {
Reflect.apply(error);
reached = true;
} catch (e) {
assertTrue(e.stack.indexOf(err_str_1) != -1);
} finally {
assertFalse(reached);
}
reached = false;
error = new Error();
error.msg = error;
try {
Reflect.apply(error);
reached = true;
} catch (e) {
assertTrue(e.stack.indexOf(err_str_2) != -1);
} finally {
assertFalse(reached);
}
reached = false;
error = new Error();
error.name = error;
error.msg = error;
try {
Reflect.apply(error);
reached = true;
} catch (e) {
assertTrue(e.stack.indexOf(err_str_1) != -1);
} finally {
assertFalse(reached);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment