This is the other half of the patch for bug 188229 that I missed checking in earlier. Again, this isn't part of the regular build.

git-svn-id: svn://10.0.0.236/trunk@139371 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
dbradley%netscape.com 2003-03-13 04:13:05 +00:00
parent bf9cc3a7d5
commit d4d963f3a5
4 changed files with 208 additions and 3 deletions

View File

@ -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<nsIScriptSecurityManager> 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<nsIJSContextStack> 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(&currentCX)))
{
// 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<nsIPrincipal> 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<nsIDOMWindow> window;
NPN_GetValue(pData->pPluginInstance, NPNVDOMWindow,
NS_STATIC_CAST(nsIDOMWindow **, getter_AddRefs(window)));
if (!window)
return nsnull;
nsCOMPtr<nsIScriptGlobalObject> globalObject(do_QueryInterface(window));
if (!globalObject)
return nsnull;
nsCOMPtr<nsIScriptContext> 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<nsIURI> 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;
}

View File

@ -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) \

View File

@ -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<nsIDOMWindow> domWindow;
NPN_GetValue(instance, NPNVDOMWindow, (void *) &domWindow);
if (!domWindow)
{
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMWindowInternal> windowInternal = do_QueryInterface(domWindow);
if (!windowInternal)
{
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMLocation> 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)

View File

@ -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
}