Bug 641378 - Don't try to treat an nsXPCWrappedJS as the interface we asked for. r=peterv

--HG--
extra : rebase_source : 8faddb67c5daa0c1bb52d5a5b9b5b16537b7f5f0
This commit is contained in:
Blake Kaplan 2011-04-08 14:28:24 -07:00
parent bf58da448d
commit 786e379831
2 changed files with 55 additions and 6 deletions

View File

@ -1640,10 +1640,13 @@ XPCConvert::JSValToXPCException(XPCCallContext& ccx,
JSBool found;
// heuristic to see if it might be usable as an xpcexception
if(JS_GetPropertyAttributes(cx, obj, "message", &ignored, &found) &&
found &&
JS_GetPropertyAttributes(cx, obj, "result", &ignored, &found) &&
found)
if(!JS_GetPropertyAttributes(cx, obj, "message", &ignored, &found))
return NS_ERROR_FAILURE;
if(found && !JS_GetPropertyAttributes(cx, obj, "result", &ignored, &found))
return NS_ERROR_FAILURE;
if(found)
{
// lets try to build a wrapper around the JSObject
nsXPCWrappedJS* jswrapper;
@ -1653,8 +1656,8 @@ XPCConvert::JSValToXPCException(XPCCallContext& ccx,
nsnull, &jswrapper);
if(NS_FAILED(rv))
return rv;
*exceptn = reinterpret_cast<nsIException*>
(jswrapper);
*exceptn = static_cast<nsIException *>(jswrapper->GetXPTCStub());
return NS_OK;
}

View File

@ -0,0 +1,46 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
var timer;
// This test XPConnect's ability to deal with a certain type of exception. In
// particular, bug 641378 meant that if an exception had both 'message' and
// 'result' properties, then it wouldn't successfully read the 'result' field
// out of the exception (and sometimes crash).
//
// In order to make the test not fail completely on a negative result, we use
// a timer. The first time through the timer, we throw our special exception.
// Then, the second time through, we can test to see if XPConnect properly
// dealt with our exception.
var exception = {
message: "oops, something failed!",
tries: 0,
get result() {
++this.tries;
return 3;
}
};
var callback = {
tries: 0,
notify: function (timer) {
if (++this.tries === 1)
throw exception;
try {
do_check_true(exception.tries >= 1);
} finally {
timer.cancel();
timer = null;
do_test_finished();
}
}
};
function run_test() {
do_test_pending();
timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback(callback, 0, timer.TYPE_REPEATING_SLACK);
}