Commit 1e462860 authored by lrn@chromium.org's avatar lrn@chromium.org

Add missing check to StringBuilderConcat runtime function.

Review URL: http://codereview.chromium.org/1578036

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4449 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent cdbbd7fa
...@@ -1798,8 +1798,6 @@ class ReplacementStringBuilder { ...@@ -1798,8 +1798,6 @@ class ReplacementStringBuilder {
void AddSubjectSlice(int from, int to) { void AddSubjectSlice(int from, int to) {
AddSubjectSlice(&array_builder_, from, 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); IncrementCharacterCount(to - from);
} }
...@@ -5427,7 +5425,7 @@ static Object* Runtime_StringAdd(Arguments args) { ...@@ -5427,7 +5425,7 @@ static Object* Runtime_StringAdd(Arguments args) {
} }
template<typename sinkchar> template <typename sinkchar>
static inline void StringBuilderConcatHelper(String* special, static inline void StringBuilderConcatHelper(String* special,
sinkchar* sink, sinkchar* sink,
FixedArray* fixed_array, FixedArray* fixed_array,
...@@ -5498,33 +5496,41 @@ static Object* Runtime_StringBuilderConcat(Arguments args) { ...@@ -5498,33 +5496,41 @@ static Object* Runtime_StringBuilderConcat(Arguments args) {
bool ascii = special->IsAsciiRepresentation(); bool ascii = special->IsAsciiRepresentation();
int position = 0; int position = 0;
int increment = 0;
for (int i = 0; i < array_length; i++) { for (int i = 0; i < array_length; i++) {
int increment = 0;
Object* elt = fixed_array->get(i); Object* elt = fixed_array->get(i);
if (elt->IsSmi()) { if (elt->IsSmi()) {
// Smi encoding of position and length. // Smi encoding of position and length.
int len = Smi::cast(elt)->value(); int smi_value = Smi::cast(elt)->value();
if (len > 0) { int pos;
int len;
if (smi_value > 0) {
// Position and length encoded in one smi. // Position and length encoded in one smi.
int pos = len >> 11; pos = StringBuilderSubstringPosition::decode(smi_value);
len &= 0x7ff; len = StringBuilderSubstringLength::decode(smi_value);
if (pos + len > special_length) {
return Top::Throw(Heap::illegal_argument_symbol());
}
increment = len;
} else { } else {
// Position and length encoded in two smis. // Position and length encoded in two smis.
increment = (-len); len = -smi_value;
// Get the position and check that it is also a smi. // Get the position and check that it is a positive smi.
i++; i++;
if (i >= array_length) { if (i >= array_length) {
return Top::Throw(Heap::illegal_argument_symbol()); return Top::Throw(Heap::illegal_argument_symbol());
} }
Object* pos = fixed_array->get(i); Object* next_smi = fixed_array->get(i);
if (!pos->IsSmi()) { if (!next_smi->IsSmi()) {
return Top::Throw(Heap::illegal_argument_symbol()); 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()) { } else if (elt->IsString()) {
String* element = String::cast(elt); String* element = String::cast(elt);
int element_length = element->length(); int element_length = element->length();
......
...@@ -931,10 +931,10 @@ ReplaceResultBuilder.prototype.add = function(str) { ...@@ -931,10 +931,10 @@ ReplaceResultBuilder.prototype.add = function(str) {
ReplaceResultBuilder.prototype.addSpecialSlice = function(start, end) { ReplaceResultBuilder.prototype.addSpecialSlice = function(start, end) {
var len = end - start; var len = end - start;
if (len == 0) return; if (start < 0 || len <= 0) return;
var elements = this.elements; var elements = this.elements;
if (start < 0x80000 && len < 0x800) { if (start < 0x80000 && len < 0x800) {
elements[elements.length] = (start << 11) + len; elements[elements.length] = (start << 11) | len;
} else { } else {
// 0 < len <= String::kMaxLength and Smi::kMaxValue >= String::kMaxLength, // 0 < len <= String::kMaxLength and Smi::kMaxValue >= String::kMaxLength,
// so -len is a smi. // so -len is a smi.
......
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