From 58c82e93b36d8e1ef6fd0ecc72acb7fce4c08988 Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Thu, 25 Oct 2012 12:36:40 +0000 Subject: [PATCH] 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 --- src/json-parser.h | 10 +++++++++- test/mjsunit/json-recursive.js | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/json-parser.h b/src/json-parser.h index 9aa4201..d481ed0 100644 --- a/src/json-parser.h +++ b/src/json-parser.h @@ -195,8 +195,10 @@ Handle JsonParser::ParseJson(Handle source, AdvanceSkipWhitespace(); Handle 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::null(); + // Parse failed. Current character is the unexpected token. const char* message; Factory* factory = this->factory(); Handle array; @@ -247,6 +249,12 @@ Handle JsonParser::ParseJson(Handle source, // Parse any JSON value. template Handle JsonParser::ParseJsonValue() { + StackLimitCheck stack_check(isolate_); + if (stack_check.HasOverflowed()) { + isolate_->StackOverflow(); + return Handle::null(); + } + if (c0_ == '"') return ParseJsonString(); if ((c0_ >= '0' && c0_ <= '9') || c0_ == '-') return ParseJsonNumber(); if (c0_ == '{') return ParseJsonObject(); diff --git a/test/mjsunit/json-recursive.js b/test/mjsunit/json-recursive.js index adfd93b..0ecca2b 100644 --- a/test/mjsunit/json-recursive.js +++ b/test/mjsunit/json-recursive.js @@ -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); -- 2.7.4