| Index: src/json-stringifier.h
|
| diff --git a/src/json-stringifier.h b/src/json-stringifier.h
|
| index 175b9a16c76812f7950418985cc15cf63fcd8ce8..a75b3deed50eacb0863ef2eed4957302674e3ac6 100644
|
| --- a/src/json-stringifier.h
|
| +++ b/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,7 +257,10 @@ 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()));
|
| @@ -269,9 +275,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)));
|
| @@ -486,7 +495,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;
|
| }
|
|
|
| @@ -708,8 +719,20 @@ 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.
|
| + // We most likely will trigger a real OOM before even reaching this point.
|
| + 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;
|
| }
|
| @@ -724,7 +747,7 @@ void BasicJsonStringifier::Extend() {
|
|
|
| void BasicJsonStringifier::ChangeEncoding() {
|
| ShrinkCurrentPart();
|
| - set_accumulator(factory_->NewConsString(accumulator(), current_part_));
|
| + Accumulate();
|
| current_part_ = factory_->NewRawTwoByteString(part_length_);
|
| current_index_ = 0;
|
| is_ascii_ = false;
|
|
|