Bug 609066 - nsIJetpack.registerReceiver doesn't recognize functions wrapped in a proxy, throws NS_ERROR_ILLEGAL_VALUE. Don't use JS_ObjectIsFunction, instead use JS_TypeOfValue to determine whether we have a legal receiver. r?mrbkap
authorBenjamin Smedberg <benjamin@smedbergs.us>
Wed, 17 Nov 2010 15:58:08 -0500
changeset 57665 b5c6ae71b2eb913394d3e54ff852ef4f32a90776
parent 57664 238d99ca6886dccc32a6599184c5dc855ed55254
child 57666 3862e43372ba848dc57e0d1702100ae06d0d672b
push id17031
push userbsmedberg@mozilla.com
push dateWed, 17 Nov 2010 21:02:34 +0000
treeherdermozilla-central@a86f1ab3f3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs609066
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 609066 - nsIJetpack.registerReceiver doesn't recognize functions wrapped in a proxy, throws NS_ERROR_ILLEGAL_VALUE. Don't use JS_ObjectIsFunction, instead use JS_TypeOfValue to determine whether we have a legal receiver. r?mrbkap
js/jetpack/JetpackActorCommon.cpp
js/jetpack/JetpackChild.cpp
js/jetpack/JetpackParent.cpp
js/jetpack/tests/unit/test_jetpack_sandbox.js
--- a/js/jetpack/JetpackActorCommon.cpp
+++ b/js/jetpack/JetpackActorCommon.cpp
@@ -528,18 +528,17 @@ JetpackActorCommon::RecList::copyTo(nsTA
     dst.AppendElement(node->value());
 }
 
 nsresult
 JetpackActorCommon::RegisterReceiver(JSContext* cx,
                                      const nsString& messageName,
                                      jsval receiver)
 {
-  if (!JSVAL_IS_OBJECT(receiver) ||
-      !JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(receiver)))
+  if (JS_TypeOfValue(cx, receiver) != JSTYPE_FUNCTION)
     return NS_ERROR_INVALID_ARG;
 
   RecList* list;
   if (!mReceivers.Get(messageName, &list)) {
     list = new RecList(cx);
     if (!list || !mReceivers.Put(messageName, list)) {
       delete list;
       return NS_ERROR_OUT_OF_MEMORY;
--- a/js/jetpack/JetpackChild.cpp
+++ b/js/jetpack/JetpackChild.cpp
@@ -356,19 +356,17 @@ ReceiverCommon(JSContext* cx, uintN argc
   }
 
   result->msgName.Assign((PRUnichar*)JS_GetStringChars(str),
                          JS_GetStringLength(str));
 
   if (arity < 2)
     return JS_TRUE;
 
-  if (!JSVAL_IS_OBJECT(argv[1]) ||
-      !JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(argv[1])))
-  {
+  if (JS_TypeOfValue(cx, argv[1]) != JSTYPE_FUNCTION) {
     JS_ReportError(cx, "%s expects a function as its second argument",
                    methodName);
     return JS_FALSE;
   }
 
   // GC-safe because argv is rooted.
   result->receiver = argv[1];
 
--- a/js/jetpack/JetpackParent.cpp
+++ b/js/jetpack/JetpackParent.cpp
@@ -260,16 +260,19 @@ JetpackParent::CreateHandle(nsIVariant**
 
 NS_IMETHODIMP
 JetpackParent::Destroy()
 {
   if (mSubprocess)
     Close();
 
   NS_ASSERTION(!mSubprocess, "ActorDestroy should have been called.");
+
+  ClearReceivers();
+
   return NS_OK;
 }
 
 PHandleParent*
 JetpackParent::AllocPHandle()
 {
   return new HandleParent();
 }
new file mode 100644
--- /dev/null
+++ b/js/jetpack/tests/unit/test_jetpack_sandbox.js
@@ -0,0 +1,19 @@
+function run_test() {
+    var jetpack = createJetpack({ scriptFile: do_get_file("impl.js") });
+  
+  var sandbox = Components.utils.Sandbox("about:blank");
+  function registerReceiver(name, fn) {
+    jetpack.registerReceiver(name, fn);
+  }
+  sandbox.registerReceiver = registerReceiver;
+  sandbox.echoed = function(message, arg) {
+    do_check_eq(message, "echo");
+    do_check_eq(arg, "testdata");
+    jetpack.destroy();
+    sandbox = null;
+    do_test_finished();
+  };
+  Components.utils.evalInSandbox("registerReceiver('echo', function(message, arg){ echoed(message, arg); });", sandbox);
+  jetpack.sendMessage("echo", "testdata");
+  do_test_pending();
+}