diff --git a/mozilla/embedding/browser/activex/src/plugin/LegacyPlugin.cpp b/mozilla/embedding/browser/activex/src/plugin/LegacyPlugin.cpp index 9e3720456b9..99a850d4965 100644 --- a/mozilla/embedding/browser/activex/src/plugin/LegacyPlugin.cpp +++ b/mozilla/embedding/browser/activex/src/plugin/LegacyPlugin.cpp @@ -60,7 +60,14 @@ #include "nsIDocument.h" #include "nsIDOMElement.h" #include "nsIDOMDocument.h" +#include "nsIDOMWindow.h" +#include "nsIScriptGlobalObject.h" +#include "nsIScriptContext.h" #include "nsIURI.h" +#include "nsIJSContextStack.h" +#include "jsapi.h" +#include "jscntxt.h" +#include "nsIScriptSecurityManager.h" #endif /////////////////////////////////////////////////////////////////////////////// @@ -330,8 +337,146 @@ NewScript(const char *pluginType, return NPERR_GENERIC_ERROR; } +#if defined(MOZ_ACTIVEX_PLUGIN_XPCONNECT) && defined(XPC_IDISPATCH_SUPPORT) + +static nsresult +CreatePrincipal(nsIURI * origin, + nsIPrincipal ** outPrincipal) +{ + nsresult rv; + nsCOMPtr secMan( + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv)); + if (NS_FAILED(rv)) return rv; + + return secMan->GetCodebasePrincipal(origin, outPrincipal); +} + +/***************************************************************************/ +// A class to put on the stack to manage JS contexts when we are entering JS. +// This pushes and pops the given context +// with the nsThreadJSContextStack service as this object goes into and out +// of scope. It is optimized to not push/pop the cx if it is already on top +// of the stack. We need to push the JSContext when we enter JS because the +// JS security manager looks on the context stack for permissions information. + +class MozAxAutoPushJSContext +{ +public: + MozAxAutoPushJSContext(JSContext *cx, nsIURI * aURI); + + ~MozAxAutoPushJSContext(); + + nsresult ResultOfPush() { return mPushResult; }; + +private: + nsCOMPtr mContextStack; + JSContext* mContext; + JSStackFrame mFrame; + nsresult mPushResult; +}; + + +MozAxAutoPushJSContext::MozAxAutoPushJSContext(JSContext *cx, + nsIURI * aURI) + : mContext(cx), mPushResult(NS_OK) +{ + mContextStack = do_GetService("@mozilla.org/js/xpc/ContextStack;1"); + + if(mContextStack) + { + JSContext* currentCX; + if(NS_SUCCEEDED(mContextStack->Peek(¤tCX))) + { + // Is the current context already on the stack? + if(cx == currentCX) + mContextStack = nsnull; + else + { + mContextStack->Push(cx); + // Leave the reference to the mContextStack to + // indicate that we need to pop it in our dtor. + } + + } + } + + memset(&mFrame, 0, sizeof(mFrame)); + + // See if there are any scripts on the stack. + // If not, we need to add a dummy frame with a principal. + PRBool hasScript = PR_FALSE; + JSStackFrame* tempFP = cx->fp; + while (tempFP) + { + if (tempFP->script) + { + hasScript = PR_TRUE; + break; + } + tempFP = tempFP->down; + }; + + if (!hasScript) + { + nsCOMPtr principal; + mPushResult = CreatePrincipal(aURI, getter_AddRefs(principal)); + + if (NS_SUCCEEDED(mPushResult)) + { + JSPrincipals* jsprinc; + principal->GetJSPrincipals(&jsprinc); + + mFrame.script = JS_CompileScriptForPrincipals(cx, JS_GetGlobalObject(cx), + jsprinc, "", 0, "", 1); + JSPRINCIPALS_DROP(cx, jsprinc); + + if (mFrame.script) + { + mFrame.down = cx->fp; + cx->fp = &mFrame; + } + else + mPushResult = NS_ERROR_OUT_OF_MEMORY; + } + } +} + +MozAxAutoPushJSContext::~MozAxAutoPushJSContext() +{ + if (mContextStack) + mContextStack->Pop(nsnull); + + if (mFrame.script) + mContext->fp = mFrame.down; + +} + + +static JSContext* +GetPluginsContext(PluginInstanceData *pData) +{ + nsCOMPtr window; + NPN_GetValue(pData->pPluginInstance, NPNVDOMWindow, + NS_STATIC_CAST(nsIDOMWindow **, getter_AddRefs(window))); + if (!window) + return nsnull; + + nsCOMPtr globalObject(do_QueryInterface(window)); + if (!globalObject) + return nsnull; + + nsCOMPtr scriptContext; + if (NS_FAILED(globalObject->GetContext(getter_AddRefs(scriptContext))) || + !scriptContext) + return nsnull; + + return NS_REINTERPRET_CAST(JSContext*, scriptContext->GetNativeContext()); +} + +#endif + static BOOL -WillHandleCLSID(const CLSID &clsid) +WillHandleCLSID(const CLSID &clsid, PluginInstanceData *pData) { #if defined(MOZ_ACTIVEX_PLUGIN_XPCONNECT) && defined(XPC_IDISPATCH_SUPPORT) // Ensure the control is safe for scripting @@ -342,7 +487,14 @@ WillHandleCLSID(const CLSID &clsid) memcpy(&cid, &clsid, sizeof(nsCID)); PRBool isSafe = PR_FALSE; PRBool classExists = PR_FALSE; - dispSupport->IsClassSafeToHost(cid, &classExists, &isSafe); + JSContext * cx = GetPluginsContext(pData); + if (cx) + { + nsCOMPtr uri; + MozAxPlugin::GetCurrentLocation(pData->pPluginInstance, getter_AddRefs(uri)); + MozAxAutoPushJSContext autoContext(cx, uri); + dispSupport->IsClassSafeToHost(cx, cid, PR_TRUE, &classExists, &isSafe); + } if (classExists && !isSafe) return FALSE; return TRUE; @@ -443,7 +595,7 @@ static NPError CreateControl(const CLSID &clsid, PluginInstanceData *pData, PropertyList &pl, LPCOLESTR szCodebase) { // Make sure we got a CLSID we can handle - if (!WillHandleCLSID(clsid)) + if (!WillHandleCLSID(clsid, pData)) { return NPERR_GENERIC_ERROR; } diff --git a/mozilla/embedding/browser/activex/src/plugin/Makefile.in b/mozilla/embedding/browser/activex/src/plugin/Makefile.in index e46593d07f5..41c154fbafa 100644 --- a/mozilla/embedding/browser/activex/src/plugin/Makefile.in +++ b/mozilla/embedding/browser/activex/src/plugin/Makefile.in @@ -52,6 +52,13 @@ REQUIRES = \ necko \ windowwatcher \ $(NULL) + +ifdef XPC_IDISPATCH_SUPPORT +REQUIRES += \ + caps \ + embedstring \ + $(NULL) +endif XPIFILE = mozactivex.xpi FORCE_SHARED_LIB = 1 @@ -176,6 +183,12 @@ EXTRA_DSO_LDOPTS = \ $(NSPR_LIBS) \ $(NULL) +ifdef XPC_IDISPATCH_SUPPORT +EXTRA_DSO_LDOPTS += \ + $(MOZ_JS_LIBS) \ + $(NULL) +endif + LIBS = \ $(DIST)/lib/$(LIB_PREFIX)string_s.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)string_obsolete_s.$(LIB_SUFFIX) \ diff --git a/mozilla/embedding/browser/activex/src/plugin/XPConnect.cpp b/mozilla/embedding/browser/activex/src/plugin/XPConnect.cpp index fc5b3faaee9..25d9a876901 100644 --- a/mozilla/embedding/browser/activex/src/plugin/XPConnect.cpp +++ b/mozilla/embedding/browser/activex/src/plugin/XPConnect.cpp @@ -68,6 +68,14 @@ #include "LegacyPlugin.h" #include "XPConnect.h" +#ifdef XPC_IDISPATCH_SUPPORT +#include "nsIDOMWindowInternal.h" +#include "nsIDOMLocation.h" +#include "nsNetUtil.h" +#include "nsEmbedString.h" +#include "nsIURI.h" +#endif + static NS_DEFINE_IID(kIClassInfoIID, NS_ICLASSINFO_IID); static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); @@ -937,6 +945,36 @@ void MozAxPlugin::Release() } } +#ifdef XPC_IDISPATCH_SUPPORT +nsresult MozAxPlugin::GetCurrentLocation(NPP instance, nsIURI **aLocation) +{ + NS_ENSURE_ARG_POINTER(aLocation); + *aLocation = nsnull; + nsCOMPtr domWindow; + NPN_GetValue(instance, NPNVDOMWindow, (void *) &domWindow); + if (!domWindow) + { + return NS_ERROR_FAILURE; + } + nsCOMPtr windowInternal = do_QueryInterface(domWindow); + if (!windowInternal) + { + return NS_ERROR_FAILURE; + } + + nsCOMPtr location; + nsEmbedString href; + windowInternal->GetLocation(getter_AddRefs(location)); + if (!location || + NS_FAILED(location->GetHref(href))) + { + return NS_ERROR_FAILURE; + } + + return NS_NewURI(aLocation, href); +} +#endif + CLSID MozAxPlugin::GetCLSIDForType(const char *mimeType) { if (mimeType == NULL) diff --git a/mozilla/embedding/browser/activex/src/plugin/XPConnect.h b/mozilla/embedding/browser/activex/src/plugin/XPConnect.h index a7b03ae4907..5c2f33e7eaf 100644 --- a/mozilla/embedding/browser/activex/src/plugin/XPConnect.h +++ b/mozilla/embedding/browser/activex/src/plugin/XPConnect.h @@ -51,6 +51,7 @@ #include "nsIClassInfo.h" #include "nsIMozAxPlugin.h" #include "nsIServiceManagerUtils.h" +#include "nsIURI.h" #include "ControlEventSink.h" @@ -152,6 +153,7 @@ namespace MozAxPlugin { #ifdef XPC_IDISPATCH_SUPPORT extern PRUint32 PrefGetHostingFlags(); extern void ReleasePrefObserver(); + extern nsresult GetCurrentLocation(NPP instance, nsIURI **aLocation); #endif }