Commit 4b7d5dc4 authored by yangguo's avatar yangguo Committed by Commit bot

Protect error message formatter against invalid string length.

R=mstarzinger@chromium.org
BUG=chromium:500980
LOG=N

Review URL: https://codereview.chromium.org/1191263002

Cr-Commit-Position: refs/heads/master@{#29135}
parent 37928334
......@@ -331,6 +331,7 @@ MaybeHandle<String> MessageTemplate::FormatMessage(int template_index,
Handle<String> arg0,
Handle<String> arg1,
Handle<String> arg2) {
static const int kMaxArgLength = 256;
Isolate* isolate = arg0->GetIsolate();
const char* template_string;
switch (template_index) {
......@@ -358,7 +359,17 @@ MaybeHandle<String> MessageTemplate::FormatMessage(int template_index,
builder.AppendCharacter('%');
} else {
DCHECK(i < arraysize(args));
builder.AppendString(args[i++]);
Handle<String> arg = args[i++];
int length = arg->length();
if (length > kMaxArgLength) {
builder.AppendString(
isolate->factory()->NewSubString(arg, 0, kMaxArgLength - 6));
builder.AppendCString("...");
builder.AppendString(
isolate->factory()->NewSubString(arg, length - 3, length));
} else {
builder.AppendString(arg);
}
}
} else {
builder.AppendCharacter(*c);
......
......@@ -55,25 +55,23 @@ IncrementalStringBuilder::IncrementalStringBuilder(Isolate* isolate)
}
void IncrementalStringBuilder::Accumulate() {
// Only accumulate fully written strings. Shrink first if necessary.
DCHECK_EQ(current_index_, current_part()->length());
void IncrementalStringBuilder::Accumulate(Handle<String> new_part) {
Handle<String> new_accumulator;
if (accumulator()->length() + current_part()->length() > String::kMaxLength) {
if (accumulator()->length() + new_part->length() > String::kMaxLength) {
// Set the flag and carry on. Delay throwing the exception till the end.
new_accumulator = factory()->empty_string();
overflowed_ = true;
} else {
new_accumulator = factory()
->NewConsString(accumulator(), current_part())
.ToHandleChecked();
new_accumulator =
factory()->NewConsString(accumulator(), new_part).ToHandleChecked();
}
set_accumulator(new_accumulator);
}
void IncrementalStringBuilder::Extend() {
Accumulate();
DCHECK_EQ(current_index_, current_part()->length());
Accumulate(current_part());
if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) {
part_length_ *= kPartLengthGrowthFactor;
}
......@@ -91,7 +89,7 @@ void IncrementalStringBuilder::Extend() {
MaybeHandle<String> IncrementalStringBuilder::Finish() {
ShrinkCurrentPart();
Accumulate();
Accumulate(current_part());
if (overflowed_) {
THROW_NEW_ERROR(isolate_, NewInvalidStringLengthError(), String);
}
......@@ -103,9 +101,7 @@ void IncrementalStringBuilder::AppendString(Handle<String> string) {
ShrinkCurrentPart();
part_length_ = kInitialPartLength; // Allocate conservatively.
Extend(); // Attach current part and allocate new part.
Handle<String> concat =
factory()->NewConsString(accumulator(), string).ToHandleChecked();
set_accumulator(concat);
Accumulate(string);
}
} // namespace internal
} // namespace v8
......@@ -384,7 +384,7 @@ class IncrementalStringBuilder {
}
// Add the current part to the accumulator.
void Accumulate();
void Accumulate(Handle<String> new_part);
// Finish the current part and allocate a new part.
void Extend();
......
// 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 a = "a";
assertThrows(function() { while (true) a += a; }, RangeError);
assertThrows(function() { a in a; }, TypeError);
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