Fix stack capture on overflow for Error.stackTraceLimit == Infinity
authorwingo@igalia.com <wingo@igalia.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 20 Jun 2014 14:27:55 +0000 (14:27 +0000)
committerwingo@igalia.com <wingo@igalia.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 20 Jun 2014 14:27:55 +0000 (14:27 +0000)
Bug found by Andrew Paprocki <andrew@ishiboo.com>.

R=mstarzinger@chromium.org, yangguo@chromium.org

Review URL: https://codereview.chromium.org/345533002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21902 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/conversions.h
src/isolate.cc
test/mjsunit/stack-traces-overflow.js

index a23ea90..0c76574 100644 (file)
@@ -41,7 +41,8 @@ inline bool isBinaryDigit(int x) {
 
 // The fast double-to-(unsigned-)int conversion routine does not guarantee
 // rounding towards zero.
-// For NaN and values outside the int range, return INT_MIN or INT_MAX.
+// If x is NaN, the result is INT_MIN.  Otherwise the result is the argument x,
+// clamped to [INT_MIN, INT_MAX] and then rounded to an integer.
 inline int FastD2IChecked(double x) {
   if (!(x >= INT_MIN)) return INT_MIN;  // Negation to catch NaNs.
   if (x > INT_MAX) return INT_MAX;
index 9ec3c9b..a4b311f 100644 (file)
@@ -792,9 +792,8 @@ Object* Isolate::StackOverflow() {
       JSObject::GetDataProperty(Handle<JSObject>::cast(error),
                                 stackTraceLimit);
   if (!stack_trace_limit->IsNumber()) return heap()->exception();
-  double dlimit = stack_trace_limit->Number();
-  int limit = std::isnan(dlimit) ? 0 : static_cast<int>(dlimit);
-
+  int limit = FastD2IChecked(stack_trace_limit->Number());
+  if (limit < 0) limit = 0;
   Handle<JSArray> stack_trace = CaptureSimpleStackTrace(
       exception, factory()->undefined_value(), limit);
   JSObject::SetHiddenProperty(exception,
index 7722e93..1c67680 100644 (file)
@@ -106,6 +106,21 @@ try {
   assertEquals(1, e.stack.split('\n').length);
 }
 
+// A limit outside the range of integers.
+Error.stackTraceLimit = 1e12;
+try {
+  rec1(0);
+} catch (e) {
+  assertTrue(e.stack.split('\n').length > 100);
+}
+
+Error.stackTraceLimit = Infinity;
+try {
+  rec1(0);
+} catch (e) {
+  assertTrue(e.stack.split('\n').length > 100);
+}
+
 Error.stackTraceLimit = "not a number";
 try {
   rec1(0);