Reviewers: Michael Starzinger,

Description:
Protect error message formatter against invalid string length.


[email protected]
BUG=chromium:500980
LOG=N

Please review this at https://codereview.chromium.org/1191263002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+24, -17 lines):
  M src/messages.cc
  M src/string-builder.h
  M src/string-builder.cc
  A + test/mjsunit/regress/regress-500980.js


Index: src/messages.cc
diff --git a/src/messages.cc b/src/messages.cc
index ce6375594f497470f2d4b7564021b933ed91aaf3..a69df0463a892b8dbcbc93d828cc726b7ace9906 100644
--- a/src/messages.cc
+++ b/src/messages.cc
@@ -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);
Index: src/string-builder.cc
diff --git a/src/string-builder.cc b/src/string-builder.cc
index c7488abb9513a29727f7e0877684343b03bbecad..7c46e0d523e41560ae633577850c2369b93bb608 100644
--- a/src/string-builder.cc
+++ b/src/string-builder.cc
@@ -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
Index: src/string-builder.h
diff --git a/src/string-builder.h b/src/string-builder.h
index 43b690dba38228d73a7b79c21465e8644f8b031d..5314665329988104347557d139da3713ad51dedf 100644
--- a/src/string-builder.h
+++ b/src/string-builder.h
@@ -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();
Index: test/mjsunit/regress/regress-500980.js
diff --git a/test/message/arrow-bare-rest-param.js b/test/mjsunit/regress/regress-500980.js
similarity index 57%
copy from test/message/arrow-bare-rest-param.js
copy to test/mjsunit/regress/regress-500980.js
index 9b3916d95952e7eb3f5cd61d02f634a994071c43..841d26aa4a64882a26cf2bc572ff0844082e4885 100644
--- a/test/message/arrow-bare-rest-param.js
+++ b/test/mjsunit/regress/regress-500980.js
@@ -1,7 +1,7 @@
 // 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.
-//
-// Flags: --harmony-rest-parameters --harmony-arrow-functions

-...x => 10
+var a = "a";
+assertThrows(function() { while (true) a += a; }, RangeError);
+assertThrows(function() { a in a; }, TypeError);


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to