Reviewers: Mads Ager,

Description:
Do not invoke any setters when forming stack trace JS object.

Please review this at http://codereview.chromium.org/6463022/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/top.cc
  M test/cctest/test-api.cc


Index: src/top.cc
diff --git a/src/top.cc b/src/top.cc
index e32eb6bc8b2677b64db262582b9c48c112d4033b..35387281f0e825cf8e8812ad7abf9038c2b9b828 100644
--- a/src/top.cc
+++ b/src/top.cc
@@ -374,22 +374,34 @@ Handle<String> Top::StackTraceString() {
 }


+static void SetLocalProperty(Handle<JSObject> object,
+                             Handle<String> key,
+                             Handle<Object> value) {
+  // We set properties on freshly allocated JS object, nothing
+  // should fail except for OOM which is handled by
+  // SetLocalPropertyIgnoreAttributes.
+  ASSERT(!Top::has_pending_exception());
+ CHECK(!SetLocalPropertyIgnoreAttributes(object, key, value, NONE).is_null());
+  CHECK(!Top::has_pending_exception());
+}
+
+
 Handle<JSArray> Top::CaptureCurrentStackTrace(
     int frame_limit, StackTrace::StackTraceOptions options) {
   // Ensure no negative values.
   int limit = Max(frame_limit, 0);
   Handle<JSArray> stack_trace = Factory::NewJSArray(frame_limit);

-  Handle<String> column_key =  Factory::LookupAsciiSymbol("column");
-  Handle<String> line_key =  Factory::LookupAsciiSymbol("lineNumber");
-  Handle<String> script_key =  Factory::LookupAsciiSymbol("scriptName");
+  Handle<String> column_key = Factory::LookupAsciiSymbol("column");
+  Handle<String> line_key = Factory::LookupAsciiSymbol("lineNumber");
+  Handle<String> script_key = Factory::LookupAsciiSymbol("scriptName");
   Handle<String> name_or_source_url_key =
       Factory::LookupAsciiSymbol("nameOrSourceURL");
   Handle<String> script_name_or_source_url_key =
       Factory::LookupAsciiSymbol("scriptNameOrSourceURL");
- Handle<String> function_key = Factory::LookupAsciiSymbol("functionName");
-  Handle<String> eval_key =  Factory::LookupAsciiSymbol("isEval");
- Handle<String> constructor_key = Factory::LookupAsciiSymbol("isConstructor");
+  Handle<String> function_key = Factory::LookupAsciiSymbol("functionName");
+  Handle<String> eval_key = Factory::LookupAsciiSymbol("isEval");
+ Handle<String> constructor_key = Factory::LookupAsciiSymbol("isConstructor");

   StackTraceFrameIterator it;
   int frames_seen = 0;
@@ -421,16 +433,16 @@ Handle<JSArray> Top::CaptureCurrentStackTrace(
             // tag.
             column_offset += script->column_offset()->value();
           }
-          SetProperty(stackFrame, column_key,
-                      Handle<Smi>(Smi::FromInt(column_offset + 1)), NONE);
+          SetLocalProperty(stackFrame, column_key,
+                           Handle<Smi>(Smi::FromInt(column_offset + 1)));
         }
-        SetProperty(stackFrame, line_key,
-                    Handle<Smi>(Smi::FromInt(line_number + 1)), NONE);
+        SetLocalProperty(stackFrame, line_key,
+                         Handle<Smi>(Smi::FromInt(line_number + 1)));
       }

       if (options & StackTrace::kScriptName) {
         Handle<Object> script_name(script->name());
-        SetProperty(stackFrame, script_key, script_name, NONE);
+        SetLocalProperty(stackFrame, script_key, script_name);
       }

       if (options & StackTrace::kScriptNameOrSourceURL) {
@@ -446,7 +458,7 @@ Handle<JSArray> Top::CaptureCurrentStackTrace(
         if (caught_exception) {
           result = Factory::undefined_value();
         }
- SetProperty(stackFrame, script_name_or_source_url_key, result, NONE); + SetLocalProperty(stackFrame, script_name_or_source_url_key, result);
       }

       if (options & StackTrace::kFunctionName) {
@@ -454,20 +466,20 @@ Handle<JSArray> Top::CaptureCurrentStackTrace(
         if (fun_name->ToBoolean()->IsFalse()) {
           fun_name = Handle<Object>(fun->shared()->inferred_name());
         }
-        SetProperty(stackFrame, function_key, fun_name, NONE);
+        SetLocalProperty(stackFrame, function_key, fun_name);
       }

       if (options & StackTrace::kIsEval) {
         int type = Smi::cast(script->compilation_type())->value();
         Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ?
             Factory::true_value() : Factory::false_value();
-        SetProperty(stackFrame, eval_key, is_eval, NONE);
+        SetLocalProperty(stackFrame, eval_key, is_eval);
       }

       if (options & StackTrace::kIsConstructor) {
         Handle<Object> is_constructor = (frames[i].is_constructor()) ?
             Factory::true_value() : Factory::false_value();
-        SetProperty(stackFrame, constructor_key, is_constructor, NONE);
+        SetLocalProperty(stackFrame, constructor_key, is_constructor);
       }

FixedArray::cast(stack_trace->elements())->set(frames_seen, *stackFrame);
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 970fdaa1ddb7db3160eaa6f6b628226278bf231d..03994cbb109944618d91d848417ca28428cf6b17 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -11353,6 +11353,26 @@ TEST(CaptureStackTraceForUncaughtException) {
 }


+TEST(CaptureStackTraceForUncaughtExceptionAndSetters) {
+  v8::HandleScope scope;
+  LocalContext env;
+  v8::V8::SetCaptureStackTraceForUncaughtExceptions(true,
+                                                    1024,
+ v8::StackTrace::kDetailed);
+
+  CompileRun(
+      "var setters = ['column', 'lineNumber', 'scriptName',\n"
+      "    'scriptNameOrSourceURL', 'functionName', 'isEval',\n"
+      "    'isConstructor'];\n"
+      "for (var i = 0; i < setters.length; i++) {\n"
+      "  var prop = setters[i];\n"
+ " Object.prototype.__defineSetter__(prop, function() { throw prop; });\n"
+      "}\n");
+  CompileRun("throw 'exception';");
+  v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
+}
+
+
v8::Handle<Value> AnalyzeStackOfEvalWithSourceURL(const v8::Arguments& args) {
   v8::HandleScope scope;
   v8::Handle<v8::StackTrace> stackTrace =


--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev

Reply via email to