Bug 475864 - Distinguish between "there is no JS code running" and "there are only native frames on the stack." Also clean up the rest of the code's handling of null fp.
authorBlake Kaplan <mrbkap@gmail.com>
Thu, 23 Apr 2009 00:21:22 -0700
changeset 27665 60980742d9da494252ab77f7b5ed8fb60c51574f
parent 27664 da473f63b7edd2b552032f0843d0e9ad043b5b64
child 27666 d6ed6486d125b61f6068e3f74a7adbdb74dfb645
push id6681
push usermrbkap@mozilla.com
push dateThu, 23 Apr 2009 07:21:38 +0000
treeherdermozilla-central@60980742d9da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs475864
milestone1.9.2a1pre
Bug 475864 - Distinguish between "there is no JS code running" and "there are only native frames on the stack." Also clean up the rest of the code's handling of null fp.
js/src/xpconnect/src/XPCSystemOnlyWrapper.cpp
--- a/js/src/xpconnect/src/XPCSystemOnlyWrapper.cpp
+++ b/js/src/xpconnect/src/XPCSystemOnlyWrapper.cpp
@@ -169,32 +169,45 @@ AllowedToAct(JSContext *cx, jsval idval)
   }
 
   JSStackFrame *fp;
   nsIPrincipal *principal = ssm->GetCxSubjectPrincipalAndFrame(cx, &fp);
   if (!principal) {
     return ThrowException(NS_ERROR_UNEXPECTED, cx);
   }
 
-  void *annotation = JS_GetFrameAnnotation(cx, fp);
+  if (!fp) {
+    if (!JS_FrameIterator(cx, &fp)) {
+      // No code at all is running. So we must be arriving here as the result
+      // of C++ code asking us to do something. Allow access.
+      return JS_TRUE;
+    }
+
+    // Some code is running, we can't make the assumption, as above, but we
+    // can't use a native frame, so clear fp.
+    fp = nsnull;
+  }
+
+  void *annotation = fp ? JS_GetFrameAnnotation(cx, fp) : nsnull;
   PRBool privileged;
-  if (fp &&
-      NS_SUCCEEDED(principal->IsCapabilityEnabled("UniversalXPConnect",
+  if (NS_SUCCEEDED(principal->IsCapabilityEnabled("UniversalXPConnect",
                                                   annotation,
                                                   &privileged)) &&
       privileged) {
     // UniversalXPConnect things are allowed to touch us.
     return JS_TRUE;
   }
 
   // XXX HACK EWW! Allow chrome://global/ access to these things, even
   // if they've been cloned into less privileged contexts.
   static const char prefix[] = "chrome://global/";
-  const char *filename = fp->script->filename;
-  if (filename && !strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) {
+  const char *filename;
+  if (fp &&
+      (filename = fp->script->filename) &&
+      !strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) {
     return JS_TRUE;
   }
 
   if (JSVAL_IS_VOID(idval)) {
     ThrowException(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx);
   } else {
     // TODO Localize me?
     JSString *str = JS_ValueToString(cx, idval);