mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 12:35:58 +00:00
Make plug-in loads of javascript: URIs execute synchronously. Bug 364028,r=biesi, sr=jst
This commit is contained in:
parent
9ba6252982
commit
2f2e06d144
@ -54,7 +54,7 @@
|
||||
* principal of the environment in which the program is to be executed the
|
||||
* execution will be forced to happen in a sandbox.
|
||||
*/
|
||||
[scriptable, uuid(6dec981b-6fce-4f57-bf97-d518c6079c77)]
|
||||
[scriptable, uuid(33234b99-9588-4c7d-9da6-86b8b7cba565)]
|
||||
interface nsIScriptChannel : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -85,4 +85,18 @@ interface nsIScriptChannel : nsISupports
|
||||
* @throws NS_ERROR_INVALID_ARG when set to an unrecognized value.
|
||||
*/
|
||||
attribute unsigned long executionPolicy;
|
||||
|
||||
/**
|
||||
* Control whether the program should be executed synchronosly when
|
||||
* the channel's AsyncOpen method is called or whether it should be
|
||||
* executed asynchronously. In both cases, any data that the
|
||||
* channel returns will be returned asynchronously; the only thing
|
||||
* this property affects is when the program executes.
|
||||
*
|
||||
* The default value of this property is TRUE.
|
||||
*
|
||||
* Setting this property after asyncOpen has been called on the
|
||||
* channel has no effect.
|
||||
*/
|
||||
attribute boolean executeAsync;
|
||||
};
|
||||
|
@ -429,6 +429,7 @@ protected:
|
||||
nsRefPtr<nsJSThunk> mIOThunk;
|
||||
PopupControlState mPopupState;
|
||||
PRUint32 mExecutionPolicy;
|
||||
PRPackedBool mIsAsync;
|
||||
PRPackedBool mIsActive;
|
||||
PRPackedBool mOpenedStreamChannel;
|
||||
};
|
||||
@ -439,6 +440,7 @@ nsJSChannel::nsJSChannel() :
|
||||
mActualLoadFlags(LOAD_NORMAL),
|
||||
mPopupState(openOverridden),
|
||||
mExecutionPolicy(EXECUTE_IN_SANDBOX),
|
||||
mIsAsync(PR_TRUE),
|
||||
mIsActive(PR_FALSE),
|
||||
mOpenedStreamChannel(PR_FALSE)
|
||||
{
|
||||
@ -630,9 +632,42 @@ nsJSChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
|
||||
loadGroup->AddRequest(this, nsnull);
|
||||
}
|
||||
|
||||
// post an event to do the rest
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new nsRunnableMethod<nsJSChannel>(this, &nsJSChannel::EvaluateScript);
|
||||
mPopupState = win->GetPopupControlState();
|
||||
|
||||
nsRunnableMethod<nsJSChannel>::Method method;
|
||||
if (mIsAsync) {
|
||||
// post an event to do the rest
|
||||
method = &nsJSChannel::EvaluateScript;
|
||||
} else {
|
||||
EvaluateScript();
|
||||
if (mOpenedStreamChannel) {
|
||||
// That will handle notifying things
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(NS_FAILED(mStatus), "We should have failed _somehow_");
|
||||
|
||||
// mStatus is going to be NS_ERROR_DOM_RETVAL_UNDEFINED if we didn't
|
||||
// have any content resulting from the execution and NS_BINDING_ABORTED
|
||||
// if something we did causes our own load to be stopped. Return
|
||||
// success in those cases, and error out in all others.
|
||||
if (mStatus != NS_ERROR_DOM_RETVAL_UNDEFINED &&
|
||||
mStatus != NS_BINDING_ABORTED) {
|
||||
// Note that calling EvaluateScript() handled removing us from the
|
||||
// loadgroup and marking us as not active anymore.
|
||||
mListener = nsnull;
|
||||
mContext = nsnull;
|
||||
mOriginalInnerWindow = nsnull;
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
// We're returning success from asyncOpen(), but we didn't open a
|
||||
// stream channel. We'll have to notify ourselves, but make sure to do
|
||||
// it asynchronously.
|
||||
method = &nsJSChannel::NotifyListener;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> ev = new nsRunnableMethod<nsJSChannel>(this, method);
|
||||
nsresult rv = NS_DispatchToCurrentThread(ev);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -642,9 +677,6 @@ nsJSChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
|
||||
mContext = nsnull;
|
||||
mOriginalInnerWindow = nsnull;
|
||||
}
|
||||
|
||||
mPopupState = win->GetPopupControlState();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -687,7 +719,9 @@ nsJSChannel::EvaluateScript()
|
||||
mIsActive = PR_FALSE;
|
||||
|
||||
if (NS_FAILED(mStatus)) {
|
||||
NotifyListener();
|
||||
if (mIsAsync) {
|
||||
NotifyListener();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -729,17 +763,19 @@ nsJSChannel::EvaluateScript()
|
||||
}
|
||||
|
||||
if (NS_FAILED(mStatus)) {
|
||||
NotifyListener();
|
||||
if (mIsAsync) {
|
||||
NotifyListener();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mStatus = mStreamChannel->AsyncOpen(this, mContext);
|
||||
if (NS_FAILED(mStatus)) {
|
||||
NotifyListener();
|
||||
} else {
|
||||
if (NS_SUCCEEDED(mStatus)) {
|
||||
// mStreamChannel will call OnStartRequest and OnStopRequest on
|
||||
// us, so we'll be sure to call them on our listener.
|
||||
mOpenedStreamChannel = PR_TRUE;
|
||||
} else if (mIsAsync) {
|
||||
NotifyListener();
|
||||
}
|
||||
|
||||
return;
|
||||
@ -920,6 +956,25 @@ nsJSChannel::GetExecutionPolicy(PRUint32* aPolicy)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJSChannel::SetExecuteAsync(PRBool aIsAsync)
|
||||
{
|
||||
if (!mIsActive) {
|
||||
mIsAsync = aIsAsync;
|
||||
}
|
||||
// else ignore this call
|
||||
NS_WARN_IF_FALSE(!mIsActive, "Calling SetExecuteAsync on active channel?");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJSChannel::GetExecuteAsync(PRBool* aIsAsync)
|
||||
{
|
||||
*aIsAsync = mIsAsync;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsJSProtocolHandler::nsJSProtocolHandler()
|
||||
|
@ -5809,6 +5809,8 @@ NS_IMETHODIMP nsPluginHostImpl::NewPluginURLStream(const nsString& aURL,
|
||||
nsCOMPtr<nsIScriptChannel> scriptChannel(do_QueryInterface(channel));
|
||||
if (scriptChannel) {
|
||||
scriptChannel->SetExecutionPolicy(nsIScriptChannel::EXECUTE_NORMAL);
|
||||
// Plug-ins seem to depend on javascript: URIs running synchronously
|
||||
scriptChannel->SetExecuteAsync(PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user