Do not use js builtins object when constructing an error.
R=cbruni@chromium.org Review URL: https://codereview.chromium.org/1295093002 Cr-Commit-Position: refs/heads/master@{#30189}
This commit is contained in:
parent
f0c21aa487
commit
d281688ae5
@ -1763,6 +1763,7 @@ void Bootstrapper::ImportNatives(Isolate* isolate, Handle<JSObject> container) {
|
||||
INSTALL_NATIVE(JSFunction, "SyntaxError", syntax_error_function);
|
||||
INSTALL_NATIVE(JSFunction, "TypeError", type_error_function);
|
||||
INSTALL_NATIVE(JSFunction, "URIError", uri_error_function);
|
||||
INSTALL_NATIVE(JSFunction, "MakeError", make_error_function);
|
||||
|
||||
INSTALL_NATIVE(Symbol, "promiseStatus", promise_status);
|
||||
INSTALL_NATIVE(Symbol, "promiseValue", promise_value);
|
||||
|
@ -159,6 +159,7 @@ enum BindingFlags {
|
||||
V(SYNTAX_ERROR_FUNCTION_INDEX, JSFunction, syntax_error_function) \
|
||||
V(TYPE_ERROR_FUNCTION_INDEX, JSFunction, type_error_function) \
|
||||
V(URI_ERROR_FUNCTION_INDEX, JSFunction, uri_error_function) \
|
||||
V(MAKE_ERROR_FUNCTION_INDEX, JSFunction, make_error_function) \
|
||||
V(PROMISE_STATUS_INDEX, Symbol, promise_status) \
|
||||
V(PROMISE_VALUE_INDEX, Symbol, promise_value) \
|
||||
V(PROMISE_CREATE_INDEX, JSFunction, promise_create) \
|
||||
|
135
src/factory.cc
135
src/factory.cc
@ -1103,137 +1103,23 @@ Handle<Bool8x16> Factory::NewBool8x16(bool lanes[16], PretenureFlag pretenure) {
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> Factory::NewError(const char* maker,
|
||||
Handle<Object> Factory::NewError(Handle<JSFunction> constructor,
|
||||
MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0, Handle<Object> arg1,
|
||||
Handle<Object> arg2) {
|
||||
HandleScope scope(isolate());
|
||||
Handle<String> error_maker = InternalizeUtf8String(maker);
|
||||
if (isolate()->bootstrapper()->IsActive()) {
|
||||
// If this exception is being thrown during bootstrapping,
|
||||
// js_builtins_object is unavailable. We return the error maker
|
||||
// name's string as the exception since we have nothing better
|
||||
// to do.
|
||||
return scope.CloseAndEscape(error_maker);
|
||||
// During bootstrapping we cannot construct error objects.
|
||||
return scope.CloseAndEscape(NewStringFromAsciiChecked(
|
||||
MessageTemplate::TemplateString(template_index)));
|
||||
}
|
||||
Handle<Object> fun_obj = Object::GetProperty(isolate()->js_builtins_object(),
|
||||
error_maker).ToHandleChecked();
|
||||
|
||||
Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj);
|
||||
Handle<JSFunction> fun = isolate()->make_error_function();
|
||||
Handle<Object> message_type(Smi::FromInt(template_index), isolate());
|
||||
if (arg0.is_null()) arg0 = undefined_value();
|
||||
if (arg1.is_null()) arg1 = undefined_value();
|
||||
if (arg2.is_null()) arg2 = undefined_value();
|
||||
Handle<Object> argv[] = {message_type, arg0, arg1, arg2};
|
||||
|
||||
// Invoke the JavaScript factory method. If an exception is thrown while
|
||||
// running the factory method, use the exception as the result.
|
||||
Handle<Object> result;
|
||||
MaybeHandle<Object> exception;
|
||||
if (!Execution::TryCall(fun, isolate()->js_builtins_object(), arraysize(argv),
|
||||
argv, &exception).ToHandle(&result)) {
|
||||
Handle<Object> exception_obj;
|
||||
if (exception.ToHandle(&exception_obj)) {
|
||||
result = exception_obj;
|
||||
} else {
|
||||
result = undefined_value();
|
||||
}
|
||||
}
|
||||
return scope.CloseAndEscape(result);
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> Factory::NewError(MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0, Handle<Object> arg1,
|
||||
Handle<Object> arg2) {
|
||||
return NewError("MakeError", template_index, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> Factory::NewTypeError(MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0, Handle<Object> arg1,
|
||||
Handle<Object> arg2) {
|
||||
return NewError("MakeTypeError", template_index, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> Factory::NewSyntaxError(MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0, Handle<Object> arg1,
|
||||
Handle<Object> arg2) {
|
||||
return NewError("MakeSyntaxError", template_index, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> Factory::NewReferenceError(
|
||||
MessageTemplate::Template template_index, Handle<Object> arg0,
|
||||
Handle<Object> arg1, Handle<Object> arg2) {
|
||||
return NewError("MakeReferenceError", template_index, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> Factory::NewRangeError(MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0, Handle<Object> arg1,
|
||||
Handle<Object> arg2) {
|
||||
return NewError("MakeRangeError", template_index, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> Factory::NewEvalError(MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0, Handle<Object> arg1,
|
||||
Handle<Object> arg2) {
|
||||
return NewError("MakeEvalError", template_index, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
|
||||
Handle<String> Factory::EmergencyNewError(const char* message,
|
||||
Handle<JSArray> args) {
|
||||
const int kBufferSize = 1000;
|
||||
char buffer[kBufferSize];
|
||||
size_t space = kBufferSize;
|
||||
char* p = &buffer[0];
|
||||
|
||||
Vector<char> v(buffer, kBufferSize);
|
||||
StrNCpy(v, message, space);
|
||||
space -= Min(space, strlen(message));
|
||||
p = &buffer[kBufferSize] - space;
|
||||
|
||||
for (int i = 0; i < Smi::cast(args->length())->value(); i++) {
|
||||
if (space > 0) {
|
||||
*p++ = ' ';
|
||||
space--;
|
||||
if (space > 0) {
|
||||
Handle<String> arg_str = Handle<String>::cast(
|
||||
Object::GetElement(isolate(), args, i).ToHandleChecked());
|
||||
base::SmartArrayPointer<char> arg = arg_str->ToCString();
|
||||
Vector<char> v2(p, static_cast<int>(space));
|
||||
StrNCpy(v2, arg.get(), space);
|
||||
space -= Min(space, strlen(arg.get()));
|
||||
p = &buffer[kBufferSize] - space;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (space > 0) {
|
||||
*p = '\0';
|
||||
} else {
|
||||
buffer[kBufferSize - 1] = '\0';
|
||||
}
|
||||
return NewStringFromUtf8(CStrVector(buffer), TENURED).ToHandleChecked();
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> Factory::NewError(const char* maker, const char* message,
|
||||
Handle<JSArray> args) {
|
||||
Handle<String> make_str = InternalizeUtf8String(maker);
|
||||
Handle<Object> fun_obj = Object::GetProperty(
|
||||
isolate()->js_builtins_object(), make_str).ToHandleChecked();
|
||||
// If the builtins haven't been properly configured yet this error
|
||||
// constructor may not have been defined. Bail out.
|
||||
if (!fun_obj->IsJSFunction()) {
|
||||
return EmergencyNewError(message, args);
|
||||
}
|
||||
Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj);
|
||||
Handle<Object> message_obj = InternalizeUtf8String(message);
|
||||
Handle<Object> argv[] = { message_obj, args };
|
||||
Handle<Object> argv[] = {constructor, message_type, arg0, arg1, arg2};
|
||||
|
||||
// Invoke the JavaScript factory method. If an exception is thrown while
|
||||
// running the factory method, use the exception as the result.
|
||||
@ -1243,10 +1129,13 @@ Handle<Object> Factory::NewError(const char* maker, const char* message,
|
||||
&exception)
|
||||
.ToHandle(&result)) {
|
||||
Handle<Object> exception_obj;
|
||||
if (exception.ToHandle(&exception_obj)) return exception_obj;
|
||||
return undefined_value();
|
||||
if (exception.ToHandle(&exception_obj)) {
|
||||
result = exception_obj;
|
||||
} else {
|
||||
result = undefined_value();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return scope.CloseAndEscape(result);
|
||||
}
|
||||
|
||||
|
||||
|
@ -546,11 +546,6 @@ class Factory final {
|
||||
Handle<Code> CopyCode(Handle<Code> code, Vector<byte> reloc_info);
|
||||
|
||||
// Interface for creating error objects.
|
||||
|
||||
Handle<Object> NewError(const char* maker, const char* message,
|
||||
Handle<JSArray> args);
|
||||
Handle<String> EmergencyNewError(const char* message, Handle<JSArray> args);
|
||||
|
||||
Handle<Object> NewError(Handle<JSFunction> constructor,
|
||||
Handle<String> message);
|
||||
|
||||
@ -558,41 +553,28 @@ class Factory final {
|
||||
return NewRangeError(MessageTemplate::kInvalidStringLength);
|
||||
}
|
||||
|
||||
Handle<Object> NewError(const char* maker,
|
||||
Handle<Object> NewError(Handle<JSFunction> constructor,
|
||||
MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0 = Handle<Object>(),
|
||||
Handle<Object> arg1 = Handle<Object>(),
|
||||
Handle<Object> arg2 = Handle<Object>());
|
||||
|
||||
Handle<Object> NewError(MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0 = Handle<Object>(),
|
||||
Handle<Object> arg1 = Handle<Object>(),
|
||||
Handle<Object> arg2 = Handle<Object>());
|
||||
#define DEFINE_ERROR(NAME, name) \
|
||||
Handle<Object> New##NAME(MessageTemplate::Template template_index, \
|
||||
Handle<Object> arg0 = Handle<Object>(), \
|
||||
Handle<Object> arg1 = Handle<Object>(), \
|
||||
Handle<Object> arg2 = Handle<Object>()) { \
|
||||
return NewError(isolate()->name##_function(), template_index, arg0, arg1, \
|
||||
arg2); \
|
||||
}
|
||||
|
||||
Handle<Object> NewTypeError(MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0 = Handle<Object>(),
|
||||
Handle<Object> arg1 = Handle<Object>(),
|
||||
Handle<Object> arg2 = Handle<Object>());
|
||||
|
||||
Handle<Object> NewSyntaxError(MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0 = Handle<Object>(),
|
||||
Handle<Object> arg1 = Handle<Object>(),
|
||||
Handle<Object> arg2 = Handle<Object>());
|
||||
|
||||
Handle<Object> NewReferenceError(MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0 = Handle<Object>(),
|
||||
Handle<Object> arg1 = Handle<Object>(),
|
||||
Handle<Object> arg2 = Handle<Object>());
|
||||
|
||||
Handle<Object> NewRangeError(MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0 = Handle<Object>(),
|
||||
Handle<Object> arg1 = Handle<Object>(),
|
||||
Handle<Object> arg2 = Handle<Object>());
|
||||
|
||||
Handle<Object> NewEvalError(MessageTemplate::Template template_index,
|
||||
Handle<Object> arg0 = Handle<Object>(),
|
||||
Handle<Object> arg1 = Handle<Object>(),
|
||||
Handle<Object> arg2 = Handle<Object>());
|
||||
DEFINE_ERROR(Error, error)
|
||||
DEFINE_ERROR(EvalError, eval_error)
|
||||
DEFINE_ERROR(RangeError, range_error)
|
||||
DEFINE_ERROR(ReferenceError, reference_error)
|
||||
DEFINE_ERROR(SyntaxError, syntax_error)
|
||||
DEFINE_ERROR(TypeError, type_error)
|
||||
#undef DEFINE_ERROR
|
||||
|
||||
Handle<String> NumberToString(Handle<Object> number,
|
||||
bool check_number_string_cache = true);
|
||||
|
@ -322,23 +322,29 @@ Handle<String> MessageTemplate::FormatMessage(Isolate* isolate,
|
||||
}
|
||||
|
||||
|
||||
const char* MessageTemplate::TemplateString(int template_index) {
|
||||
switch (template_index) {
|
||||
#define CASE(NAME, STRING) \
|
||||
case k##NAME: \
|
||||
return STRING;
|
||||
MESSAGE_TEMPLATES(CASE)
|
||||
#undef CASE
|
||||
case kLastMessage:
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<String> MessageTemplate::FormatMessage(int template_index,
|
||||
Handle<String> arg0,
|
||||
Handle<String> arg1,
|
||||
Handle<String> arg2) {
|
||||
Isolate* isolate = arg0->GetIsolate();
|
||||
const char* template_string;
|
||||
switch (template_index) {
|
||||
#define CASE(NAME, STRING) \
|
||||
case k##NAME: \
|
||||
template_string = STRING; \
|
||||
break;
|
||||
MESSAGE_TEMPLATES(CASE)
|
||||
#undef CASE
|
||||
case kLastMessage:
|
||||
default:
|
||||
isolate->ThrowIllegalOperation();
|
||||
return MaybeHandle<String>();
|
||||
const char* template_string = TemplateString(template_index);
|
||||
if (template_string == NULL) {
|
||||
isolate->ThrowIllegalOperation();
|
||||
return MaybeHandle<String>();
|
||||
}
|
||||
|
||||
IncrementalStringBuilder builder(isolate);
|
||||
|
@ -413,6 +413,8 @@ class MessageTemplate {
|
||||
kLastMessage
|
||||
};
|
||||
|
||||
static const char* TemplateString(int template_index);
|
||||
|
||||
static MaybeHandle<String> FormatMessage(int template_index,
|
||||
Handle<String> arg0,
|
||||
Handle<String> arg1,
|
||||
|
@ -172,7 +172,6 @@ function ToDetailString(obj) {
|
||||
|
||||
|
||||
function MakeGenericError(constructor, type, arg0, arg1, arg2) {
|
||||
if (IS_UNDEFINED(arg0) && IS_STRING(type)) arg0 = [];
|
||||
var error = new constructor(FormatMessage(type, arg0, arg1, arg2));
|
||||
error[$internalErrorSymbol] = true;
|
||||
return error;
|
||||
@ -1014,18 +1013,10 @@ MakeError = function(type, arg0, arg1, arg2) {
|
||||
return MakeGenericError(GlobalError, type, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
MakeEvalError = function(type, arg0, arg1, arg2) {
|
||||
return MakeGenericError(GlobalEvalError, type, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
MakeRangeError = function(type, arg0, arg1, arg2) {
|
||||
return MakeGenericError(GlobalRangeError, type, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
MakeReferenceError = function(type, arg0, arg1, arg2) {
|
||||
return MakeGenericError(GlobalReferenceError, type, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
MakeSyntaxError = function(type, arg0, arg1, arg2) {
|
||||
return MakeGenericError(GlobalSyntaxError, type, arg0, arg1, arg2);
|
||||
}
|
||||
@ -1067,6 +1058,7 @@ utils.ExportToRuntime(function(to) {
|
||||
to.GetStackTraceLine = GetStackTraceLine;
|
||||
to.NoSideEffectToString = NoSideEffectToString;
|
||||
to.ToDetailString = ToDetailString;
|
||||
to.MakeError = MakeGenericError;
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -31,10 +31,10 @@ void PendingCompilationErrorHandler::ThrowPendingError(Isolate* isolate,
|
||||
Handle<Object> error;
|
||||
switch (error_type_) {
|
||||
case kReferenceError:
|
||||
error = factory->NewError("MakeReferenceError", message_, argument);
|
||||
error = factory->NewReferenceError(message_, argument);
|
||||
break;
|
||||
case kSyntaxError:
|
||||
error = factory->NewError("MakeSyntaxError", message_, argument);
|
||||
error = factory->NewSyntaxError(message_, argument);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
|
@ -25,8 +25,6 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
// Check that message and name are not enumerable on Error objects.
|
||||
var desc = Object.getOwnPropertyDescriptor(Error.prototype, 'name');
|
||||
assertFalse(desc['enumerable']);
|
||||
@ -62,7 +60,12 @@ var e = new ReferenceError('123');
|
||||
assertTrue(e.hasOwnProperty('message'));
|
||||
assertTrue(e.hasOwnProperty('stack'));
|
||||
|
||||
var e = %MakeReferenceError("my_test_error", [0, 1]);
|
||||
try {
|
||||
eval("var error = reference");
|
||||
} catch (error) {
|
||||
e = error;
|
||||
}
|
||||
|
||||
assertTrue(e.hasOwnProperty('stack'));
|
||||
|
||||
// Check that intercepting property access from toString is prevented for
|
||||
|
Loading…
Reference in New Issue
Block a user