Correctly check for stack limit in JSON.stringify.
Changes include: - inline functions in a way as not to waste stack space. - reset StackReserveSize to the value prior to r12808. - check stack overflow dynamically. R=ulan@chromium.org BUG= Review URL: https://chromiumcodereview.appspot.com/11271021 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12814 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
b55988625d
commit
e40b33d39e
@ -180,11 +180,6 @@
|
||||
'defines': [
|
||||
'V8_TARGET_ARCH_IA32',
|
||||
],
|
||||
'msvs_settings': {
|
||||
'VCLinkerTool': {
|
||||
'StackReserveSize': '4194304',
|
||||
},
|
||||
},
|
||||
}], # v8_target_arch=="ia32"
|
||||
['v8_target_arch=="mipsel"', {
|
||||
'defines': [
|
||||
@ -251,7 +246,7 @@
|
||||
},
|
||||
'msvs_settings': {
|
||||
'VCLinkerTool': {
|
||||
'StackReserveSize': '8388608',
|
||||
'StackReserveSize': '2097152',
|
||||
},
|
||||
},
|
||||
'msvs_configuration_platform': 'x64',
|
||||
|
@ -45,7 +45,6 @@ class BasicJsonStringifier BASE_EMBEDDED {
|
||||
static const int kInitialPartLength = 32;
|
||||
static const int kMaxPartLength = 16 * 1024;
|
||||
static const int kPartLengthGrowthFactor = 2;
|
||||
static const int kStackLimit = 4 * 1024;
|
||||
|
||||
enum Result { UNCHANGED, SUCCESS, BAILOUT, CIRCULAR, STACK_OVERFLOW };
|
||||
|
||||
@ -77,10 +76,10 @@ class BasicJsonStringifier BASE_EMBEDDED {
|
||||
}
|
||||
}
|
||||
|
||||
INLINE(Handle<Object> GetProperty(Handle<JSObject> object,
|
||||
Handle<String> key));
|
||||
Handle<Object> GetProperty(Handle<JSObject> object,
|
||||
Handle<String> key);
|
||||
|
||||
INLINE(bool MayHaveToJsonFunction(Handle<JSObject> object));
|
||||
bool MayHaveToJsonFunction(Handle<JSObject> object);
|
||||
|
||||
INLINE(Result Serialize(Handle<Object> object)) {
|
||||
return Serialize_<false>(object);
|
||||
@ -98,22 +97,21 @@ class BasicJsonStringifier BASE_EMBEDDED {
|
||||
bool comma = false,
|
||||
Handle<String> key = Handle<String>::null());
|
||||
|
||||
INLINE(void SerializeDeferredKey(bool deferred_comma,
|
||||
Handle<String> deferred_key)) {
|
||||
void SerializeDeferredKey(bool deferred_comma, Handle<String> deferred_key) {
|
||||
if (deferred_comma) Append(',');
|
||||
SerializeString(deferred_key);
|
||||
Append(':');
|
||||
}
|
||||
|
||||
INLINE(Result SerializeSmi(Smi* object));
|
||||
Result SerializeSmi(Smi* object);
|
||||
|
||||
INLINE(Result SerializeDouble(double number));
|
||||
Result SerializeDouble(double number);
|
||||
INLINE(Result SerializeHeapNumber(Handle<HeapNumber> object)) {
|
||||
return SerializeDouble(object->value());
|
||||
}
|
||||
|
||||
Result SerializeArray(Handle<JSArray> object);
|
||||
Result SerializeObject(Handle<JSObject> object);
|
||||
INLINE(Result SerializeArray(Handle<JSArray> object));
|
||||
INLINE(Result SerializeObject(Handle<JSObject> object));
|
||||
|
||||
void SerializeString(Handle<String> object);
|
||||
|
||||
@ -132,8 +130,8 @@ class BasicJsonStringifier BASE_EMBEDDED {
|
||||
template <typename Char>
|
||||
INLINE(Vector<const Char> GetCharVector(Handle<String> string));
|
||||
|
||||
INLINE(Result StackPush(Handle<Object> object));
|
||||
INLINE(void StackPop());
|
||||
Result StackPush(Handle<Object> object);
|
||||
void StackPop();
|
||||
|
||||
INLINE(Handle<String> accumulator()) {
|
||||
return Handle<String>(String::cast(accumulator_store_->value()));
|
||||
@ -298,8 +296,10 @@ bool BasicJsonStringifier::MayHaveToJsonFunction(Handle<JSObject> object) {
|
||||
|
||||
BasicJsonStringifier::Result BasicJsonStringifier::StackPush(
|
||||
Handle<Object> object) {
|
||||
StackLimitCheck check(isolate_);
|
||||
if (check.HasOverflowed()) return STACK_OVERFLOW;
|
||||
|
||||
int length = Smi::cast(stack_->length())->value();
|
||||
if (length > kStackLimit) return STACK_OVERFLOW;
|
||||
FixedArray* elements = FixedArray::cast(stack_->elements());
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (elements->get(i) == *object) {
|
||||
@ -473,9 +473,8 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeObject(
|
||||
GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw);
|
||||
if (threw) return BAILOUT;
|
||||
Append('{');
|
||||
int length = contents->length();
|
||||
bool comma = false;
|
||||
for (int i = 0; i < length; i++) {
|
||||
for (int i = 0; i < contents->length(); i++) {
|
||||
Object* key = contents->get(i);
|
||||
Handle<String> key_handle;
|
||||
Handle<Object> property;
|
||||
|
@ -42,15 +42,17 @@ assertThrows(function() { rec(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4) },
|
||||
RangeError);
|
||||
|
||||
|
||||
var depth1 = 2048;
|
||||
var depth2 = 10000;
|
||||
var deepArray = [];
|
||||
for (var i = 0; i < 2048; i++) deepArray = [deepArray];
|
||||
for (var i = 0; i < depth1; i++) deepArray = [deepArray];
|
||||
JSON.stringify(deepArray);
|
||||
for (var i = 2048; i < 4097; i++) deepArray = [deepArray];
|
||||
for (var i = depth1; i < depth2; i++) deepArray = [deepArray];
|
||||
assertThrows(function() { JSON.stringify(deepArray); }, RangeError);
|
||||
|
||||
|
||||
var deepObject = {};
|
||||
for (var i = 0; i < 2048; i++) deepObject = { next: deepObject };
|
||||
for (var i = 0; i < depth1; i++) deepObject = { next: deepObject };
|
||||
JSON.stringify(deepObject);
|
||||
for (var i = 2048; i < 4097; i++) deepObject = { next: deepObject };
|
||||
for (var i = depth1; i < depth2; i++) deepObject = { next: deepObject };
|
||||
assertThrows(function() { JSON.stringify(deepObject); }, RangeError);
|
||||
|
Loading…
Reference in New Issue
Block a user