Revision: 4449
Author: [email protected]
Date: Tue Apr 20 06:10:18 2010
Log: Add missing check to StringBuilderConcat runtime function.

Review URL: http://codereview.chromium.org/1578036
http://code.google.com/p/v8/source/detail?r=4449

Modified:
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/string.js

=======================================
--- /branches/bleeding_edge/src/runtime.cc      Mon Apr 19 09:08:26 2010
+++ /branches/bleeding_edge/src/runtime.cc      Tue Apr 20 06:10:18 2010
@@ -1798,8 +1798,6 @@

   void AddSubjectSlice(int from, int to) {
     AddSubjectSlice(&array_builder_, from, to);
-    // Can we encode the slice in 11 bits for length and 19 bits for
-    // start position - as used by StringBuilderConcatHelper?
     IncrementCharacterCount(to - from);
   }

@@ -5427,7 +5425,7 @@
 }


-template<typename sinkchar>
+template <typename sinkchar>
 static inline void StringBuilderConcatHelper(String* special,
                                              sinkchar* sink,
                                              FixedArray* fixed_array,
@@ -5498,33 +5496,41 @@

   bool ascii = special->IsAsciiRepresentation();
   int position = 0;
-  int increment = 0;
   for (int i = 0; i < array_length; i++) {
+    int increment = 0;
     Object* elt = fixed_array->get(i);
     if (elt->IsSmi()) {
       // Smi encoding of position and length.
-      int len = Smi::cast(elt)->value();
-      if (len > 0) {
+      int smi_value = Smi::cast(elt)->value();
+      int pos;
+      int len;
+      if (smi_value > 0) {
         // Position and length encoded in one smi.
-        int pos = len >> 11;
-        len &= 0x7ff;
-        if (pos + len > special_length) {
-          return Top::Throw(Heap::illegal_argument_symbol());
-        }
-        increment = len;
+        pos = StringBuilderSubstringPosition::decode(smi_value);
+        len = StringBuilderSubstringLength::decode(smi_value);
       } else {
         // Position and length encoded in two smis.
-        increment = (-len);
-        // Get the position and check that it is also a smi.
+        len = -smi_value;
+        // Get the position and check that it is a positive smi.
         i++;
         if (i >= array_length) {
           return Top::Throw(Heap::illegal_argument_symbol());
         }
-        Object* pos = fixed_array->get(i);
-        if (!pos->IsSmi()) {
+        Object* next_smi = fixed_array->get(i);
+        if (!next_smi->IsSmi()) {
           return Top::Throw(Heap::illegal_argument_symbol());
         }
-      }
+        pos = Smi::cast(next_smi)->value();
+        if (pos < 0) {
+          return Top::Throw(Heap::illegal_argument_symbol());
+        }
+      }
+      ASSERT(pos >= 0);
+      ASSERT(len >= 0);
+      if (pos > special_length || len > special_length - pos) {
+        return Top::Throw(Heap::illegal_argument_symbol());
+      }
+      increment = len;
     } else if (elt->IsString()) {
       String* element = String::cast(elt);
       int element_length = element->length();
=======================================
--- /branches/bleeding_edge/src/string.js       Wed Apr 14 07:46:15 2010
+++ /branches/bleeding_edge/src/string.js       Tue Apr 20 06:10:18 2010
@@ -931,10 +931,10 @@

 ReplaceResultBuilder.prototype.addSpecialSlice = function(start, end) {
   var len = end - start;
-  if (len == 0) return;
+  if (start < 0 || len <= 0) return;
   var elements = this.elements;
   if (start < 0x80000 && len < 0x800) {
-    elements[elements.length] = (start << 11) + len;
+    elements[elements.length] = (start << 11) | len;
   } else {
// 0 < len <= String::kMaxLength and Smi::kMaxValue >= String::kMaxLength,
     // so -len is a smi.

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to