Bug 330511, Plugin-in blocklisting, r+sr=jst

git-svn-id: svn://10.0.0.236/trunk@229935 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
flamingice%sourmilk.net
2007-07-14 00:28:06 +00:00
parent 122fcbd598
commit 499adb6a0e
6 changed files with 128 additions and 69 deletions

View File

@@ -152,29 +152,37 @@ nsAsyncInstantiateEvent::Run()
}
/**
* A task for firing PluginNotFound DOM Events.
* A task for firing PluginNotFound and PluginBlocklisted DOM Events.
*/
class nsPluginNotFoundEvent : public nsRunnable {
class nsPluginErrorEvent : public nsRunnable {
public:
nsCOMPtr<nsIContent> mContent;
PRBool mBlocklisted;
nsPluginNotFoundEvent(nsIContent* aContent)
: mContent(aContent)
nsPluginErrorEvent(nsIContent* aContent, PRBool aBlocklisted)
: mContent(aContent),
mBlocklisted(aBlocklisted)
{}
~nsPluginNotFoundEvent() {}
~nsPluginErrorEvent() {}
NS_IMETHOD Run();
};
NS_IMETHODIMP
nsPluginNotFoundEvent::Run()
nsPluginErrorEvent::Run()
{
LOG(("OBJLC []: Firing plugin not found event for content %p\n",
mContent.get()));
nsContentUtils::DispatchTrustedEvent(mContent->GetDocument(), mContent,
NS_LITERAL_STRING("PluginNotFound"),
PR_TRUE, PR_TRUE);
if (mBlocklisted)
nsContentUtils::DispatchTrustedEvent(mContent->GetDocument(), mContent,
NS_LITERAL_STRING("PluginBlocklisted"),
PR_TRUE, PR_TRUE);
else
nsContentUtils::DispatchTrustedEvent(mContent->GetDocument(), mContent,
NS_LITERAL_STRING("PluginNotFound"),
PR_TRUE, PR_TRUE);
return NS_OK;
}
@@ -426,8 +434,9 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest, nsISupports *aConte
PluginSupportState pluginState = GetPluginSupportState(thisContent,
mContentType);
// Do nothing, but fire the plugin not found event if needed
if (pluginState == ePluginUnsupported) {
FirePluginNotFound(thisContent);
if (pluginState == ePluginUnsupported ||
pluginState == ePluginBlocklisted) {
FirePluginError(thisContent, pluginState == ePluginBlocklisted);
}
if (pluginState != ePluginDisabled) {
mTypeUnsupported = PR_TRUE;
@@ -887,8 +896,9 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
// No need to load anything
PluginSupportState pluginState = GetPluginSupportState(thisContent,
aTypeHint);
if (pluginState == ePluginUnsupported) {
FirePluginNotFound(thisContent);
if (pluginState == ePluginUnsupported ||
pluginState == ePluginBlocklisted) {
FirePluginError(thisContent, pluginState == ePluginBlocklisted);
}
if (pluginState != ePluginDisabled) {
fallback.TypeUnsupported();
@@ -1193,15 +1203,16 @@ nsObjectLoadingContent::NotifyStateChanged(ObjectType aOldType,
}
/* static */ void
nsObjectLoadingContent::FirePluginNotFound(nsIContent* thisContent)
nsObjectLoadingContent::FirePluginError(nsIContent* thisContent,
PRBool blocklisted)
{
LOG(("OBJLC []: Dispatching PluginNotFound event for content %p\n",
LOG(("OBJLC []: Dispatching nsPluginErrorEvent for content %p\n",
thisContent));
nsCOMPtr<nsIRunnable> ev = new nsPluginNotFoundEvent(thisContent);
nsCOMPtr<nsIRunnable> ev = new nsPluginErrorEvent(thisContent, blocklisted);
nsresult rv = NS_DispatchToCurrentThread(ev);
if (NS_FAILED(rv)) {
NS_WARNING("failed to dispatch nsPluginNotFoundEvent");
NS_WARNING("failed to dispatch nsPluginErrorEvent");
}
}
@@ -1437,5 +1448,9 @@ nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
return ePluginUnsupported;
}
nsresult rv = host->IsPluginEnabledForType(aContentType.get());
return rv == NS_ERROR_PLUGIN_DISABLED ? ePluginDisabled : ePluginUnsupported;
if (rv == NS_ERROR_PLUGIN_DISABLED)
return ePluginDisabled;
if (rv == NS_ERROR_PLUGIN_BLOCKLISTED)
return ePluginBlocklisted;
return ePluginUnsupported;
}

View File

@@ -256,7 +256,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent
* Fires the "Plugin not found" event. This function doesn't do any checks
* whether it should be fired, the caller should do that.
*/
static void FirePluginNotFound(nsIContent* thisContent);
static void FirePluginError(nsIContent* thisContent, PRBool blocklisted);
ObjectType GetTypeOfContent(const nsCString& aMIMEType);
@@ -300,6 +300,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent
ePluginUnsupported, // The plugin is not supported (not installed, say)
ePluginDisabled, // The plugin has been explicitly disabled by the
// user.
ePluginBlocklisted, // The plugin is blocklisted and disabled
ePluginOtherState // Something else (e.g. not a plugin at all as far
// as we can tell).
};

View File

@@ -38,11 +38,12 @@
#include "nsISupports.idl"
[scriptable, uuid(42f9c725-e13d-47d5-bf1d-f9b0a9ee5cf7)]
[scriptable, uuid(e8b85cb4-6281-40b1-b54d-da825487b73a)]
interface nsIPluginTag : nsISupports
{
readonly attribute ACString description;
readonly attribute ACString filename;
readonly attribute ACString name;
attribute boolean disabled;
attribute boolean blocklisted;
};

View File

@@ -44,5 +44,6 @@
#define NS_ERROR_PLUGINS_PLUGINSNOTCHANGED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_PLUGINS,1000)
#define NS_ERROR_PLUGIN_DISABLED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_PLUGINS,1001)
#define NS_ERROR_PLUGIN_BLOCKLISTED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_PLUGINS,1002)
#endif // nsPluginError_h__

View File

@@ -531,7 +531,9 @@ PRBool nsActivePluginList::remove(nsActivePlugin * plugin)
// This method terminates all running instances of plugins and collects their
// documents to be returned through an array. This method is used
// when we are shutting down or when a plugins.refresh(1) happens.
void nsActivePluginList::stopRunning(nsISupportsArray* aReloadDocs)
// If aPluginTag is given, then only that plugin is terminated
void nsActivePluginList::stopRunning(nsISupportsArray* aReloadDocs,
nsPluginTag* aPluginTag)
{
if(mFirst == nsnull)
return;
@@ -540,7 +542,8 @@ void nsActivePluginList::stopRunning(nsISupportsArray* aReloadDocs)
for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
{
if(!p->mStopped && p->mInstance)
if(!p->mStopped && p->mInstance &&
(!aPluginTag || aPluginTag == p->mPluginTag))
{
// then determine if the plugin wants Destroy to be called after
// Set Window. This is for bug 50547.
@@ -989,13 +992,36 @@ nsPluginTag::SetDisabled(PRBool aDisabled)
if (HasFlag(NS_PLUGIN_FLAG_ENABLED) == !aDisabled)
return NS_OK;
/* TODO: stop plugin if it's currently running */
if (aDisabled)
UnMark(NS_PLUGIN_FLAG_ENABLED);
else
Mark(NS_PLUGIN_FLAG_ENABLED);
mPluginHost->UpdatePluginInfo();
mPluginHost->UpdatePluginInfo(this);
return NS_OK;
}
NS_IMETHODIMP
nsPluginTag::GetBlocklisted(PRBool* aBlocklisted)
{
*aBlocklisted = HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED);
return NS_OK;
}
NS_IMETHODIMP
nsPluginTag::SetBlocklisted(PRBool aBlocklisted)
{
if (HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED) == aBlocklisted)
return NS_OK;
if (aBlocklisted) {
Mark(NS_PLUGIN_FLAG_BLOCKLISTED);
if (HasFlag(NS_PLUGIN_FLAG_ENABLED))
UnMark(NS_PLUGIN_FLAG_ENABLED);
} else
UnMark(NS_PLUGIN_FLAG_BLOCKLISTED);
mPluginHost->UpdatePluginInfo(nsnull);
return NS_OK;
}
@@ -2753,7 +2779,7 @@ nsresult nsPluginHostImpl::ReloadPlugins(PRBool reloadPages)
// Then stop any running plugin instances but hold on to the documents in the array
// We are going to need to restart the instances in these documents later
mActivePluginList.stopRunning(instsToReload);
mActivePluginList.stopRunning(instsToReload, nsnull);
}
// clean active plugin list
@@ -3250,7 +3276,7 @@ NS_IMETHODIMP nsPluginHostImpl::Destroy(void)
// we should call nsIPluginInstance::Stop and nsIPluginInstance::SetWindow
// for those plugins who want it
mActivePluginList.stopRunning(nsnull);
mActivePluginList.stopRunning(nsnull, nsnull);
// at this point nsIPlugin::Shutdown calls will be performed if needed
mActivePluginList.shut();
@@ -4107,12 +4133,6 @@ nsPluginHostImpl::SetUpDefaultPluginInstance(const char *aMimeType,
NS_IMETHODIMP
nsPluginHostImpl::IsPluginEnabledForType(const char* aMimeType)
{
if (!mJavaEnabled && IsJavaMIMEType(aMimeType)) {
// Return DISABLED whether we have a java plugin or not -- if it's
// disabled, it's disabled.
return NS_ERROR_PLUGIN_DISABLED;
}
// Pass PR_FALSE as the second arg so we can return NS_ERROR_PLUGIN_DISABLED
// for disabled plug-ins.
nsPluginTag *plugin = FindPluginForType(aMimeType, PR_FALSE);
@@ -4120,10 +4140,19 @@ nsPluginHostImpl::IsPluginEnabledForType(const char* aMimeType)
return NS_ERROR_FAILURE;
}
if (!plugin->HasFlag(NS_PLUGIN_FLAG_ENABLED)) {
if (!mJavaEnabled && IsJavaMIMEType(aMimeType)) {
// Return DISABLED whether we have a java plugin or not -- if it's
// disabled, it's disabled.
return NS_ERROR_PLUGIN_DISABLED;
}
if (!plugin->HasFlag(NS_PLUGIN_FLAG_ENABLED)) {
if (plugin->HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED))
return NS_ERROR_PLUGIN_BLOCKLISTED;
else
return NS_ERROR_PLUGIN_DISABLED;
}
return NS_OK;
}
@@ -5035,12 +5064,13 @@ nsresult nsPluginHostImpl::ScanPluginsDirectory(nsIFile * pluginsDir,
RemoveCachedPluginsInfo(NS_ConvertUTF16toUTF8(pfd->mFilename).get(),
getter_AddRefs(pluginTag));
PRBool pluginEnabled = PR_TRUE;
PRUint32 oldFlags = NS_PLUGIN_FLAG_ENABLED;
if (pluginTag) {
// If plugin changed, delete cachedPluginTag and don't use cache
if (LL_NE(fileModTime, pluginTag->mLastModifiedTime)) {
// Plugins has changed. Don't use cached plugin info.
pluginEnabled = pluginTag->HasFlag(NS_PLUGIN_FLAG_ENABLED);
oldFlags = pluginTag->Flags() &
(NS_PLUGIN_FLAG_ENABLED | NS_PLUGIN_FLAG_BLOCKLISTED);
pluginTag = nsnull;
// plugin file changed, flag this fact
@@ -5117,9 +5147,13 @@ nsresult nsPluginHostImpl::ScanPluginsDirectory(nsIFile * pluginsDir,
pluginTag->mLibrary = pluginLibrary;
pluginTag->mLastModifiedTime = fileModTime;
if (!pluginEnabled || (IsJavaPluginTag(pluginTag) && !mJavaEnabled))
if (!(oldFlags & NS_PLUGIN_FLAG_ENABLED) ||
(IsJavaPluginTag(pluginTag) && !mJavaEnabled))
pluginTag->UnMark(NS_PLUGIN_FLAG_ENABLED);
if (oldFlags & NS_PLUGIN_FLAG_BLOCKLISTED)
pluginTag->Mark(NS_PLUGIN_FLAG_BLOCKLISTED);
// if this is unwanted plugin we are checkin for, or this is a duplicate plugin,
// add it to our cache info list so we can cache the unwantedness of this plugin
// when we sync cached plugins to registry
@@ -5223,6 +5257,11 @@ NS_IMETHODIMP nsPluginHostImpl::LoadPlugins()
if (iim)
iim->AutoRegisterInterfaces();
nsCOMPtr<nsIObserverService>
obsService(do_GetService("@mozilla.org/observer-service;1"));
if (obsService)
obsService->NotifyObservers(nsnull, "plugins-list-updated", nsnull);
}
return NS_OK;
@@ -5284,7 +5323,7 @@ nsresult nsPluginHostImpl::FindPlugins(PRBool aCreatePluginList, PRBool * aPlugi
// if we are just looking for possible changes,
// no need to proceed if changes are detected
if (!aCreatePluginList && *aPluginsChanged) {
ClearCachedPluginInfoList();
mCachedPlugins = nsnull;
return NS_OK;
}
}
@@ -5311,7 +5350,7 @@ nsresult nsPluginHostImpl::FindPlugins(PRBool aCreatePluginList, PRBool * aPlugi
// if we are just looking for possible changes,
// no need to proceed if changes are detected
if (!aCreatePluginList && *aPluginsChanged) {
ClearCachedPluginInfoList();
mCachedPlugins = nsnull;
return NS_OK;
}
}
@@ -5359,7 +5398,7 @@ nsresult nsPluginHostImpl::FindPlugins(PRBool aCreatePluginList, PRBool * aPlugi
// if we are just looking for possible changes,
// no need to proceed if changes are detected
if (!aCreatePluginList && *aPluginsChanged) {
ClearCachedPluginInfoList();
mCachedPlugins = nsnull;
return NS_OK;
}
}
@@ -5387,7 +5426,7 @@ nsresult nsPluginHostImpl::FindPlugins(PRBool aCreatePluginList, PRBool * aPlugi
// if we are not creating the list, there is no need to proceed
if (!aCreatePluginList) {
ClearCachedPluginInfoList();
mCachedPlugins = nsnull;
return NS_OK;
}
@@ -5397,7 +5436,7 @@ nsresult nsPluginHostImpl::FindPlugins(PRBool aCreatePluginList, PRBool * aPlugi
WritePluginInfo();
// No more need for cached plugins. Clear it up.
ClearCachedPluginInfoList();
mCachedPlugins = nsnull;
/*
* XXX Big time hack alert!!!!
@@ -5425,11 +5464,6 @@ nsresult nsPluginHostImpl::FindPlugins(PRBool aCreatePluginList, PRBool * aPlugi
return NS_OK;
}
void nsPluginHostImpl::ClearCachedPluginInfoList()
{
mCachedPlugins = nsnull;
}
////////////////////////////////////////////////////////////////////////
nsresult
nsPluginHostImpl::LoadXPCOMPlugins(nsIComponentManager* aComponentManager)
@@ -5449,11 +5483,28 @@ nsPluginHostImpl::LoadXPCOMPlugins(nsIComponentManager* aComponentManager)
}
nsresult
nsPluginHostImpl::UpdatePluginInfo()
nsPluginHostImpl::UpdatePluginInfo(nsPluginTag* aPluginTag)
{
ReadPluginInfo();
WritePluginInfo();
ClearCachedPluginInfoList();
mCachedPlugins = nsnull;
if (!aPluginTag || aPluginTag->HasFlag(NS_PLUGIN_FLAG_ENABLED))
return NS_OK;
nsCOMPtr<nsISupportsArray> instsToReload;
NS_NewISupportsArray(getter_AddRefs(instsToReload));
mActivePluginList.stopRunning(instsToReload, aPluginTag);
mActivePluginList.removeAllStopped();
PRUint32 c;
if (instsToReload &&
NS_SUCCEEDED(instsToReload->Count(&c)) &&
c > 0) {
nsCOMPtr<nsIRunnable> ev = new nsPluginDocReframeEvent(instsToReload);
if (ev)
NS_DispatchToCurrentThread(ev);
}
return NS_OK;
}
@@ -6378,18 +6429,9 @@ NS_IMETHODIMP nsPluginHostImpl::Observe(nsISupports *aSubject,
// disabled so at least FindPluginForType/Extension doesn't return
// anything.
for (nsPluginTag* cur = mPlugins; cur; cur = cur->mNext) {
if (IsJavaPluginTag(cur)) {
if (mJavaEnabled) {
cur->Mark(NS_PLUGIN_FLAG_ENABLED);
} else {
cur->UnMark(NS_PLUGIN_FLAG_ENABLED);
}
}
if (IsJavaPluginTag(cur))
cur->SetDisabled(!mJavaEnabled);
}
// Pass PR_TRUE for reloadPages because otherwise if there is a java
// plugin running somewhere it won't get turned off
return ReloadPlugins(PR_TRUE);
}
}
return NS_OK;

View File

@@ -75,10 +75,11 @@ class nsIChannel;
class nsIRegistry;
class nsPluginHostImpl;
#define NS_PLUGIN_FLAG_ENABLED 0x0001 // is this plugin enabled?
#define NS_PLUGIN_FLAG_OLDSCHOOL 0x0002 // is this a pre-xpcom plugin?
#define NS_PLUGIN_FLAG_FROMCACHE 0x0004 // this plugintag info was loaded from cache
#define NS_PLUGIN_FLAG_UNWANTED 0x0008 // this is an unwanted plugin
#define NS_PLUGIN_FLAG_ENABLED 0x0001 // is this plugin enabled?
#define NS_PLUGIN_FLAG_OLDSCHOOL 0x0002 // is this a pre-xpcom plugin?
#define NS_PLUGIN_FLAG_FROMCACHE 0x0004 // this plugintag info was loaded from cache
#define NS_PLUGIN_FLAG_UNWANTED 0x0008 // this is an unwanted plugin
#define NS_PLUGIN_FLAG_BLOCKLISTED 0x0010 // this is a blocklisted plugin
/**
* A linked-list of plugin information that is used for
@@ -198,7 +199,7 @@ public:
PRUint32 getStoppedCount();
nsActivePlugin * findOldestStopped();
void removeAllStopped();
void stopRunning(nsISupportsArray* aReloadDocs);
void stopRunning(nsISupportsArray* aReloadDocs, nsPluginTag* aPluginTag);
PRBool IsLastInstance(nsActivePlugin * plugin);
};
@@ -319,8 +320,9 @@ public:
static nsresult GetPluginTempDir(nsIFile **aDir);
// Writes updated plugins settings to disk
nsresult UpdatePluginInfo();
// Writes updated plugins settings to disk and unloads the plugin
// if it is now disabled
nsresult UpdatePluginInfo(nsPluginTag* aPluginTag);
private:
NS_IMETHOD
@@ -409,9 +411,6 @@ private:
// that does Java)
PRBool IsJavaMIMEType(const char *aType);
// destroys plugin info list
void ClearCachedPluginInfoList();
nsresult EnsurePrivateDirServiceProvider();
nsresult GetPrompt(nsIPluginInstanceOwner *aOwner, nsIPrompt **aPrompt);