Fix for bug 760131 (Quickstub argument unwrapping fails for security-wrapped list proxy and paris binding objects). r=bz.

--HG--
extra : rebase_source : 945d58f3b73f25f05528e6c6d69745215cb4793a
This commit is contained in:
Peter Van der Beken 2012-06-01 18:24:52 +02:00
parent 36e537b8dd
commit c13ddebfa6
7 changed files with 98 additions and 22 deletions

View File

@ -40,14 +40,15 @@ enum nsDOMClassInfoID {
*
* WARNING: Be very careful when adding interfaces to this list. Every object
* that implements one of these interfaces must be directly castable
* to that interface from the *canonical* nsISupports!
* to that interface from the *canonical* nsISupports! Also, none of
* the objects that implement these interfaces may use the new DOM
* bindings.
*/
#undef DOMCI_CASTABLE_INTERFACE
#define DOMCI_CASTABLE_INTERFACES(_extra) \
DOMCI_CASTABLE_INTERFACE(nsINode, nsINode, 0, _extra) \
DOMCI_CASTABLE_INTERFACE(nsIContent, nsIContent, 1, _extra) \
DOMCI_CASTABLE_INTERFACE(nsIDocument, nsIDocument, 2, _extra) \
DOMCI_CASTABLE_INTERFACE(nsINodeList, nsINodeList, 3, _extra) \
DOMCI_CASTABLE_INTERFACE(nsICSSDeclaration, nsICSSDeclaration, 4, _extra) \
DOMCI_CASTABLE_INTERFACE(nsDocument, nsIDocument, 5, _extra) \
DOMCI_CASTABLE_INTERFACE(nsGenericHTMLElement, nsGenericHTMLElement, 6, \
@ -55,8 +56,6 @@ DOMCI_CASTABLE_INTERFACE(nsGenericHTMLElement, nsGenericHTMLElement, 6, \
DOMCI_CASTABLE_INTERFACE(nsHTMLDocument, nsIDocument, 7, _extra) \
DOMCI_CASTABLE_INTERFACE(nsStyledElement, nsStyledElement, 8, _extra) \
DOMCI_CASTABLE_INTERFACE(nsSVGStylableElement, nsIContent, 9, _extra) \
DOMCI_CASTABLE_INTERFACE(nsIDOMWebGLRenderingContext, \
nsIDOMWebGLRenderingContext, 10, _extra) \
DOMCI_CASTABLE_INTERFACE(nsIWebGLUniformLocation, \
nsIWebGLUniformLocation, 11, _extra) \
DOMCI_CASTABLE_INTERFACE(nsIDOMImageData, nsIDOMImageData, 12, _extra) \

View File

@ -63,7 +63,7 @@ IsDOMClass(const JSClass* clasp)
inline bool
IsDOMClass(const js::Class* clasp)
{
return clasp->flags & JSCLASS_IS_DOMJSCLASS;
return IsDOMClass(Jsvalify(clasp));
}
template <class T>

View File

@ -13,6 +13,7 @@
#include "XPCInlines.h"
#include "XPCQuickStubs.h"
#include "XPCWrapper.h"
#include "mozilla/dom/BindingUtils.h"
using namespace mozilla;
@ -695,20 +696,28 @@ getWrapper(JSContext *cx,
*cur = nsnull;
*tearoff = nsnull;
js::Class* clasp = js::GetObjectClass(obj);
if (dom::IsDOMClass(clasp) ||
dom::binding::instanceIsProxy(obj)) {
*cur = obj;
return NS_OK;
}
// Handle tearoffs.
//
// If |obj| is of the tearoff class, that means we're dealing with a JS
// object reflection of a particular interface (ie, |foo.nsIBar|). These
// JS objects are parented to their wrapper, so we snag the tearoff object
// along the way (if desired), and then set |obj| to its parent.
if (js::GetObjectClass(obj) == &XPC_WN_Tearoff_JSClass) {
if (clasp == &XPC_WN_Tearoff_JSClass) {
*tearoff = (XPCWrappedNativeTearOff*) js::GetObjectPrivate(obj);
obj = js::GetObjectParent(obj);
}
// If we've got a WN or slim wrapper, store things the way callers expect.
// Otherwise, leave things null and return.
if (IS_WRAPPER_CLASS(js::GetObjectClass(obj))) {
if (IS_WRAPPER_CLASS(clasp)) {
if (IS_WN_WRAPPER_OBJECT(obj))
*wrapper = (XPCWrappedNative*) js::GetObjectPrivate(obj);
else
@ -741,14 +750,18 @@ castNative(JSContext *cx,
} else if (cur) {
nsISupports *native;
QITableEntry *entries;
if (IS_SLIM_WRAPPER(cur)) {
js::Class* clasp = js::GetObjectClass(cur);
if (dom::IsDOMClass(clasp)) {
native = dom::UnwrapDOMObject<nsISupports>(cur);
entries = nsnull;
} else if (dom::binding::instanceIsProxy(cur)) {
native = static_cast<nsISupports*>(js::GetProxyPrivate(cur).toPrivate());
entries = nsnull;
} else if (IS_WRAPPER_CLASS(clasp) && IS_SLIM_WRAPPER_OBJECT(cur)) {
native = static_cast<nsISupports*>(xpc_GetJSPrivate(cur));
entries = GetOffsetsFromSlimWrapper(cur);
} else {
NS_ABORT_IF_FALSE(mozilla::dom::binding::instanceIsProxy(cur),
"what kind of wrapper is this?");
native = static_cast<nsISupports*>(js::GetProxyPrivate(cur).toPrivate());
entries = nsnull;
MOZ_NOT_REACHED("what kind of wrapper is this?");
}
if (NS_SUCCEEDED(getNative(native, entries, cur, iid, ppThis, pThisRef, vp))) {
@ -827,13 +840,8 @@ xpc_qsUnwrapArgImpl(JSContext *cx,
XPCWrappedNative *wrapper;
XPCWrappedNativeTearOff *tearoff;
JSObject *obj2;
if (mozilla::dom::binding::instanceIsProxy(src)) {
wrapper = nsnull;
obj2 = src;
} else {
rv = getWrapper(cx, src, &wrapper, &obj2, &tearoff);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = getWrapper(cx, src, &wrapper, &obj2, &tearoff);
NS_ENSURE_SUCCESS(rv, rv);
if (wrapper || obj2) {
if (NS_FAILED(castNative(cx, wrapper, obj2, tearoff, iid, ppArg,

View File

@ -425,10 +425,10 @@ castNativeFromWrapper(JSContext *cx,
if (wrapper) {
native = wrapper->GetIdentityObject();
cur = wrapper->GetFlatJSObject();
} else if (cur && IS_SLIM_WRAPPER(cur)) {
native = static_cast<nsISupports*>(xpc_GetJSPrivate(cur));
} else {
native = cur ?
static_cast<nsISupports*>(xpc_GetJSPrivate(cur)) :
nsnull;
native = nsnull;
}
*rv = NS_ERROR_XPC_BAD_CONVERT_JS;

View File

@ -68,10 +68,12 @@ _TEST_FILES = bug500931_helper.html \
file_bug706301.html \
file_exnstack.html \
file_expandosharing.html \
file_bug760131.html \
$(NULL)
_CHROME_FILES = \
test_bug361111.xul \
test_bug760131.html \
$(NULL)
ifneq ($(OS_TARGET),Android)

View File

@ -0,0 +1,23 @@
<html>
<div id="target" ontouchstart="alert();"></div>
<script type="application/javascript">
/** Test for Bug 760131 **/
function accessTouches(evt)
{
var thrown = false;
try {
var a = evt.touches;
} catch (e) {
thrown = true;
}
ok(!thrown, "Unwrapping a TouchList shouldn't throw");
}
document.getElementById("target").ontouchstart = accessTouches;
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,44 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=760131
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 760131</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=760131">Mozilla Bug 760131</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe id="frame"></iframe>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 760131 **/
var frame = document.getElementById("frame");
function runTest()
{
var win = frame.contentWindow;
win.wrappedJSObject.ok = ok;
var doc = win.document;
var empty = doc.createTouchList();
var event = doc.createEvent("touchevent");
event.initTouchEvent("touchstart", true, true, win, 0, false, false, false, false, empty, empty, empty);
doc.getElementById("target").dispatchEvent(event);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
frame.onload = runTest;
frame.src = "http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug760131.html";
</script>
</pre>
</body>
</html>