diff options
Diffstat (limited to 'deps/v8/src/json-stringifier.h')
-rw-r--r-- | deps/v8/src/json-stringifier.h | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/deps/v8/src/json-stringifier.h b/deps/v8/src/json-stringifier.h index 4510c4b45..3926969f6 100644 --- a/deps/v8/src/json-stringifier.h +++ b/deps/v8/src/json-stringifier.h @@ -51,6 +51,8 @@ class BasicJsonStringifier BASE_EMBEDDED { enum Result { UNCHANGED, SUCCESS, EXCEPTION, CIRCULAR, STACK_OVERFLOW }; + void Accumulate(); + void Extend(); void ChangeEncoding(); @@ -178,6 +180,7 @@ class BasicJsonStringifier BASE_EMBEDDED { int current_index_; int part_length_; bool is_ascii_; + bool overflowed_; static const int kJsonEscapeTableEntrySize = 8; static const char* const JsonEscapeTable; @@ -254,12 +257,16 @@ const char* const BasicJsonStringifier::JsonEscapeTable = BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate) - : isolate_(isolate), current_index_(0), is_ascii_(true) { + : isolate_(isolate), + current_index_(0), + is_ascii_(true), + overflowed_(false) { factory_ = isolate_->factory(); accumulator_store_ = Handle<JSValue>::cast( factory_->ToObject(factory_->empty_string())); part_length_ = kInitialPartLength; current_part_ = factory_->NewRawOneByteString(part_length_); + ASSERT(!current_part_.is_null()); tojson_string_ = factory_->toJSON_string(); stack_ = factory_->NewJSArray(8); } @@ -269,9 +276,12 @@ MaybeObject* BasicJsonStringifier::Stringify(Handle<Object> object) { switch (SerializeObject(object)) { case UNCHANGED: return isolate_->heap()->undefined_value(); - case SUCCESS: + case SUCCESS: { ShrinkCurrentPart(); - return *factory_->NewConsString(accumulator(), current_part_); + Accumulate(); + if (overflowed_) return isolate_->ThrowInvalidStringLength(); + return *accumulator(); + } case CIRCULAR: return isolate_->Throw(*factory_->NewTypeError( "circular_structure", HandleVector<Object>(NULL, 0))); @@ -300,6 +310,7 @@ MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate, if (object->IsOneByteRepresentationUnderneath()) { Handle<String> result = isolate->factory()->NewRawOneByteString(worst_case_length); + ASSERT(!result.is_null()); DisallowHeapAllocation no_gc; return StringifyString_<SeqOneByteString>( isolate, @@ -308,6 +319,7 @@ MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate, } else { Handle<String> result = isolate->factory()->NewRawTwoByteString(worst_case_length); + ASSERT(!result.is_null()); DisallowHeapAllocation no_gc; return StringifyString_<SeqTwoByteString>( isolate, @@ -381,13 +393,16 @@ BasicJsonStringifier::Result BasicJsonStringifier::StackPush( if (check.HasOverflowed()) return STACK_OVERFLOW; int length = Smi::cast(stack_->length())->value(); - FixedArray* elements = FixedArray::cast(stack_->elements()); - for (int i = 0; i < length; i++) { - if (elements->get(i) == *object) { - return CIRCULAR; + { + DisallowHeapAllocation no_allocation; + FixedArray* elements = FixedArray::cast(stack_->elements()); + for (int i = 0; i < length; i++) { + if (elements->get(i) == *object) { + return CIRCULAR; + } } } - stack_->EnsureSize(length + 1); + JSArray::EnsureSize(stack_, length + 1); FixedArray::cast(stack_->elements())->set(length, *object); stack_->set_length(Smi::FromInt(length + 1)); return SUCCESS; @@ -486,7 +501,9 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric( part_length_ = kInitialPartLength; // Allocate conservatively. Extend(); // Attach current part and allocate new part. // Attach result string to the accumulator. - set_accumulator(factory_->NewConsString(accumulator(), result_string)); + Handle<String> cons = factory_->NewConsString(accumulator(), result_string); + RETURN_IF_EMPTY_HANDLE_VALUE(isolate_, cons, EXCEPTION); + set_accumulator(cons); return SUCCESS; } @@ -655,7 +672,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( isolate_); } else { property = GetProperty(isolate_, object, key); - if (property.is_null()) return EXCEPTION; + RETURN_IF_EMPTY_HANDLE_VALUE(isolate_, property, EXCEPTION); } Result result = SerializeProperty(property, comma, key); if (!comma && result == SUCCESS) comma = true; @@ -687,7 +704,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( property = GetProperty(isolate_, object, key_handle); } } - if (property.is_null()) return EXCEPTION; + RETURN_IF_EMPTY_HANDLE_VALUE(isolate_, property, EXCEPTION); Result result = SerializeProperty(property, comma, key_handle); if (!comma && result == SUCCESS) comma = true; if (result >= EXCEPTION) return result; @@ -708,8 +725,19 @@ void BasicJsonStringifier::ShrinkCurrentPart() { } +void BasicJsonStringifier::Accumulate() { + if (accumulator()->length() + current_part_->length() > String::kMaxLength) { + // Screw it. Simply set the flag and carry on. Throw exception at the end. + set_accumulator(factory_->empty_string()); + overflowed_ = true; + } else { + set_accumulator(factory_->NewConsString(accumulator(), current_part_)); + } +} + + void BasicJsonStringifier::Extend() { - set_accumulator(factory_->NewConsString(accumulator(), current_part_)); + Accumulate(); if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) { part_length_ *= kPartLengthGrowthFactor; } @@ -718,14 +746,16 @@ void BasicJsonStringifier::Extend() { } else { current_part_ = factory_->NewRawTwoByteString(part_length_); } + ASSERT(!current_part_.is_null()); current_index_ = 0; } void BasicJsonStringifier::ChangeEncoding() { ShrinkCurrentPart(); - set_accumulator(factory_->NewConsString(accumulator(), current_part_)); + Accumulate(); current_part_ = factory_->NewRawTwoByteString(part_length_); + ASSERT(!current_part_.is_null()); current_index_ = 0; is_ascii_ = false; } |