Catch stack overflow in JSON.parse.

BUG=

Review URL: https://chromiumcodereview.appspot.com/11275039

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12816 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yangguo@chromium.org 2012-10-25 12:36:40 +00:00
parent ebb44f0d30
commit 58c82e93b3
2 changed files with 17 additions and 1 deletions

View File

@ -195,8 +195,10 @@ Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source,
AdvanceSkipWhitespace();
Handle<Object> result = ParseJsonValue();
if (result.is_null() || c0_ != kEndOfString) {
// Parse failed. Current character is the unexpected token.
// Some exception (for example stack overflow) is already pending.
if (isolate_->has_pending_exception()) return Handle<Object>::null();
// Parse failed. Current character is the unexpected token.
const char* message;
Factory* factory = this->factory();
Handle<JSArray> array;
@ -247,6 +249,12 @@ Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source,
// Parse any JSON value.
template <bool seq_ascii>
Handle<Object> JsonParser<seq_ascii>::ParseJsonValue() {
StackLimitCheck stack_check(isolate_);
if (stack_check.HasOverflowed()) {
isolate_->StackOverflow();
return Handle<Object>::null();
}
if (c0_ == '"') return ParseJsonString();
if ((c0_ >= '0' && c0_ <= '9') || c0_ == '-') return ParseJsonNumber();
if (c0_ == '{') return ParseJsonObject();

View File

@ -56,3 +56,11 @@ for (var i = 0; i < depth1; i++) deepObject = { next: deepObject };
JSON.stringify(deepObject);
for (var i = depth1; i < depth2; i++) deepObject = { next: deepObject };
assertThrows(function() { JSON.stringify(deepObject); }, RangeError);
var str = "[1]";
for (var i = 0; i < 100000; i++) {
str = "[1," + str + "]";
}
assertThrows(function() { JSON.parse(str); }, RangeError);