зеркало из https://github.com/mozilla/gecko-dev.git
Bug 382871 - XMLHttpRequest JS wrapper not preserved by its event handlers, r+sr=jst
This commit is contained in:
Родитель
e3596a93b4
Коммит
aa6691f983
|
@ -308,21 +308,39 @@ GetDocumentFromScriptContext(nsIScriptContext *aScriptContext)
|
|||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXHREventTarget)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXHREventTarget)
|
||||
if (tmp->mOwner) {
|
||||
nsCOMPtr<nsIDocument> doc =
|
||||
do_QueryInterface(tmp->mOwner->GetExtantDocument());
|
||||
if (doc) {
|
||||
cb.NoteXPCOMChild(doc->GetReference(tmp));
|
||||
}
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLoadListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnAbortListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLoadStartListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnProgressListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mListenerManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXHREventTarget)
|
||||
if (tmp->mOwner) {
|
||||
nsCOMPtr<nsIDocument> doc =
|
||||
do_QueryInterface(tmp->mOwner->GetExtantDocument());
|
||||
if (doc) {
|
||||
doc->RemoveReference(tmp);
|
||||
}
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLoadListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnAbortListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLoadStartListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnProgressListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mListenerManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXHREventTarget)
|
||||
|
@ -580,18 +598,18 @@ nsXHREventTarget::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXHREventTarget::GetContextForEventHandlers(nsIScriptContext** aContext)
|
||||
{
|
||||
nsresult rv = CheckInnerWindowCorrectness();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_IF_ADDREF(*aContext = mScriptContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLHttpRequestUpload)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXMLHttpRequestUpload)
|
||||
NS_INTERFACE_MAP_BEGIN(nsXMLHttpRequestUpload)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequestUpload)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(XMLHttpRequestUpload)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
|
||||
|
@ -599,12 +617,6 @@ NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
|
|||
NS_IMPL_ADDREF_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
|
||||
NS_IMPL_RELEASE_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
|
||||
|
||||
nsresult
|
||||
nsXMLHttpRequestUpload::GetContextForEventHandlers(nsIScriptContext** aContext)
|
||||
{
|
||||
return mOwner->GetContextForEventHandlers(aContext);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
@ -735,7 +747,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLHttpRequest,
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannel)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mReadRequest)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnUploadProgressListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnReadystatechangeListener)
|
||||
|
||||
|
@ -744,8 +755,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLHttpRequest,
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannelEventSink)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mProgressEventSink)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mUpload,
|
||||
nsIXMLHttpRequestUpload)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
@ -757,7 +766,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXMLHttpRequest,
|
|||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mReadRequest)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnUploadProgressListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnReadystatechangeListener)
|
||||
|
||||
|
@ -766,8 +774,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXMLHttpRequest,
|
|||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannelEventSink)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mProgressEventSink)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mUpload)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
|
@ -2577,21 +2583,15 @@ nsXMLHttpRequest::GetInterface(const nsIID & aIID, void **aResult)
|
|||
return QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXMLHttpRequest::GetContextForEventHandlers(nsIScriptContext** aContext)
|
||||
{
|
||||
nsresult rv = CheckInnerWindowCorrectness();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_IF_ADDREF(*aContext = mScriptContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXMLHttpRequest::GetUpload(nsIXMLHttpRequestUpload** aUpload)
|
||||
{
|
||||
*aUpload = nsnull;
|
||||
nsCOMPtr<nsIScriptContext> scriptContext;
|
||||
nsresult rv = GetContextForEventHandlers(getter_AddRefs(scriptContext));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mUpload) {
|
||||
mUpload = new nsXMLHttpRequestUpload(this);
|
||||
mUpload = new nsXMLHttpRequestUpload(mOwner, scriptContext);
|
||||
NS_ENSURE_TRUE(mUpload, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
NS_ADDREF(*aUpload = mUpload);
|
||||
|
|
|
@ -117,7 +117,7 @@ public:
|
|||
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID);
|
||||
virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
|
||||
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext) = 0;
|
||||
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext);
|
||||
|
||||
PRBool HasListenersFor(const nsAString& aType)
|
||||
{
|
||||
|
@ -129,6 +129,18 @@ public:
|
|||
|
||||
nsresult GetInnerEventListener(nsRefPtr<nsDOMEventListenerWrapper>& aWrapper,
|
||||
nsIDOMEventListener** aListener);
|
||||
|
||||
nsresult CheckInnerWindowCorrectness()
|
||||
{
|
||||
if (mOwner) {
|
||||
NS_ASSERTION(mOwner->IsInnerWindow(), "Should have inner window here!\n");
|
||||
nsPIDOMWindow* outer = mOwner->GetOuterWindow();
|
||||
if (!outer || outer->GetCurrentInnerWindow() != mOwner) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
protected:
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnLoadListener;
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
|
||||
|
@ -137,23 +149,26 @@ protected:
|
|||
nsRefPtr<nsDOMEventListenerWrapper> mOnProgressListener;
|
||||
nsCOMPtr<nsIEventListenerManager> mListenerManager;
|
||||
PRUint32 mLang;
|
||||
// These may be null (native callers or xpcshell).
|
||||
nsCOMPtr<nsIScriptContext> mScriptContext;
|
||||
nsCOMPtr<nsPIDOMWindow> mOwner; // Inner window.
|
||||
};
|
||||
|
||||
class nsXMLHttpRequestUpload : public nsXHREventTarget,
|
||||
public nsIXMLHttpRequestUpload
|
||||
{
|
||||
public:
|
||||
nsXMLHttpRequestUpload(nsPIDOMEventTarget* aOwner) : mOwner(aOwner) {}
|
||||
nsXMLHttpRequestUpload(nsPIDOMWindow* aOwner,
|
||||
nsIScriptContext* aScriptContext)
|
||||
{
|
||||
mOwner = aOwner;
|
||||
mScriptContext = aScriptContext;
|
||||
}
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXMLHttpRequestUpload,
|
||||
nsXHREventTarget)
|
||||
NS_FORWARD_NSIXMLHTTPREQUESTEVENTTARGET(nsXHREventTarget::)
|
||||
NS_FORWARD_NSIDOMEVENTTARGET(nsXHREventTarget::)
|
||||
NS_FORWARD_NSIDOMNSEVENTTARGET(nsXHREventTarget::)
|
||||
NS_DECL_NSIXMLHTTPREQUESTUPLOAD
|
||||
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext);
|
||||
protected:
|
||||
nsCOMPtr<nsPIDOMEventTarget> mOwner;
|
||||
};
|
||||
|
||||
class nsXMLHttpRequest : public nsXHREventTarget,
|
||||
|
@ -217,8 +232,6 @@ public:
|
|||
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
|
||||
PRUint32 argc, jsval* argv);
|
||||
|
||||
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext);
|
||||
|
||||
|
||||
// This creates a trusted readystatechange event, which is not cancelable and
|
||||
// doesn't bubble.
|
||||
|
@ -288,18 +301,6 @@ protected:
|
|||
*/
|
||||
nsresult CheckChannelForCrossSiteRequest();
|
||||
|
||||
nsresult CheckInnerWindowCorrectness()
|
||||
{
|
||||
if (mOwner) {
|
||||
NS_ASSERTION(mOwner->IsInnerWindow(), "Should have inner window here!\n");
|
||||
nsPIDOMWindow* outer = mOwner->GetOuterWindow();
|
||||
if (!outer || outer->GetCurrentInnerWindow() != mOwner) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> mContext;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
|
@ -307,10 +308,6 @@ protected:
|
|||
nsCOMPtr<nsIRequest> mReadRequest;
|
||||
nsCOMPtr<nsIDOMDocument> mDocument;
|
||||
|
||||
// These may be null (native callers or xpcshell).
|
||||
nsCOMPtr<nsIScriptContext> mScriptContext;
|
||||
nsCOMPtr<nsPIDOMWindow> mOwner; // Inner window.
|
||||
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnUploadProgressListener;
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnReadystatechangeListener;
|
||||
|
||||
|
|
|
@ -123,6 +123,7 @@ _TEST_FILES = test_bug5141.html \
|
|||
test_bug375314.html \
|
||||
test_bug378969.html \
|
||||
test_bug382113.html \
|
||||
test_bug382871.html \
|
||||
test_bug383430.html \
|
||||
test_bug390219.html \
|
||||
test_bug390735.html \
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=382871
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 382871</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=382871">Mozilla Bug 382871</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 382871 **/
|
||||
|
||||
function loadHandler(evt) {
|
||||
ok("randomProperty" in evt.target);
|
||||
ok("randomProperty" in evt.target.upload);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onload = loadHandler;
|
||||
xhr.randomProperty = true;
|
||||
xhr.upload.randomProperty = true;
|
||||
xhr.open("GET", "test_bug382871.html");
|
||||
xhr.send();
|
||||
xhr = null;
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils)
|
||||
.garbageCollect();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(runTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1208,7 +1208,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||
NS_DEFINE_CLASSINFO_DATA(XMLHttpProgressEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(XMLHttpRequest, nsEventTargetSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS |
|
||||
nsIXPCScriptable::WANT_ADDPROPERTY)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(ClientRect, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
@ -1281,7 +1282,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(XMLHttpRequestUpload, nsEventTargetSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS |
|
||||
nsIXPCScriptable::WANT_ADDPROPERTY)
|
||||
|
||||
// DOM Traversal NodeIterator class
|
||||
NS_DEFINE_CLASSINFO_DATA(NodeIterator, nsDOMGenericSH,
|
||||
|
@ -7342,6 +7344,33 @@ nsEventTargetSH::NewResolve(nsIXPConnectWrappedNative *wrapper,
|
|||
_retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEventTargetSH::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsval id, jsval *vp, PRBool *_retval)
|
||||
{
|
||||
if (id == sAddEventListener_id) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsISupports* native = wrapper->Native();
|
||||
nsCOMPtr<nsPIDOMEventTarget> target = do_QueryInterface(native);
|
||||
if (target) {
|
||||
nsCOMPtr<nsIScriptContext> scriptContext;
|
||||
target->GetContextForEventHandlers(getter_AddRefs(scriptContext));
|
||||
if (scriptContext) {
|
||||
nsCOMPtr<nsPIDOMWindow> window =
|
||||
do_QueryInterface(scriptContext->GetGlobalObject());
|
||||
if (window) {
|
||||
nsCOMPtr<nsIDocument> doc =
|
||||
do_QueryInterface(window->GetExtantDocument());
|
||||
if (doc) {
|
||||
doc->AddReference(native, wrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Element helper
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -388,6 +388,7 @@ public:
|
|||
|
||||
// Adds support for 4th parameter of addEventListener.
|
||||
// Simpler than nsEventReceiverSH
|
||||
// Makes also sure that the wrapper is preserved if new properties are added.
|
||||
class nsEventTargetSH : public nsDOMGenericSH
|
||||
{
|
||||
protected:
|
||||
|
@ -402,6 +403,8 @@ public:
|
|||
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsval id, PRUint32 flags,
|
||||
JSObject **objp, PRBool *_retval);
|
||||
NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsval id, jsval *vp, PRBool *_retval);
|
||||
|
||||
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче