Bug 1169945 - Remove unused plugins.enumerable_names whitelist. r=bsmedberg

This commit is contained in:
Chris Peterson 2015-05-29 22:42:23 -07:00
parent 06a433bde1
commit 0a651899ad
6 changed files with 35 additions and 130 deletions

View File

@ -27,8 +27,7 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsMimeTypeArray,
mWindow,
mMimeTypes,
mHiddenMimeTypes)
mMimeTypes)
nsMimeTypeArray::nsMimeTypeArray(nsPIDOMWindow* aWindow)
: mWindow(aWindow)
@ -49,7 +48,6 @@ void
nsMimeTypeArray::Refresh()
{
mMimeTypes.Clear();
mHiddenMimeTypes.Clear();
}
nsPIDOMWindow*
@ -114,10 +112,6 @@ nsMimeTypeArray::NamedGetter(const nsAString& aName, bool &aFound)
ToLowerCase(lowerName);
nsMimeType* mimeType = FindMimeType(mMimeTypes, lowerName);
if (!mimeType) {
mimeType = FindMimeType(mHiddenMimeTypes, lowerName);
}
if (mimeType) {
aFound = true;
return mimeType;
@ -164,11 +158,8 @@ nsMimeTypeArray::NamedGetter(const nsAString& aName, bool &aFound)
// If we got here, we support this type! Say so.
aFound = true;
// We don't want navigator.mimeTypes enumeration to expose MIME types with
// application handlers, so add them to the list of hidden MIME types.
nsMimeType *mt = new nsMimeType(mWindow, lowerName);
mHiddenMimeTypes.AppendElement(mt);
mMimeTypes.AppendElement(mt);
return mt;
}
@ -199,7 +190,7 @@ nsMimeTypeArray::GetSupportedNames(unsigned, nsTArray< nsString >& aRetval)
void
nsMimeTypeArray::EnsurePluginMimeTypes()
{
if (!mMimeTypes.IsEmpty() || !mHiddenMimeTypes.IsEmpty() || !mWindow) {
if (!mMimeTypes.IsEmpty() || !mWindow) {
return;
}
@ -217,7 +208,7 @@ nsMimeTypeArray::EnsurePluginMimeTypes()
return;
}
pluginArray->GetMimeTypes(mMimeTypes, mHiddenMimeTypes);
pluginArray->GetMimeTypes(mMimeTypes);
}
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsMimeType, AddRef)

View File

@ -47,16 +47,9 @@ protected:
nsCOMPtr<nsPIDOMWindow> mWindow;
// mMimeTypes contains MIME types handled by non-hidden plugins, those
// popular plugins that must be exposed in navigator.plugins enumeration to
// avoid breaking web content. Likewise, mMimeTypes are exposed in
// navigator.mimeTypes enumeration.
// mMimeTypes contains MIME types handled by plugins or by an OS
// PreferredApplicationHandler.
nsTArray<nsRefPtr<nsMimeType> > mMimeTypes;
// mHiddenMimeTypes contains MIME types handled by plugins hidden from
// navigator.plugins enumeration or by an OS PreferredApplicationHandler.
// mHiddenMimeTypes are hidden from navigator.mimeTypes enumeration.
nsTArray<nsRefPtr<nsMimeType> > mHiddenMimeTypes;
};
class nsMimeType final : public nsWrapperCache

View File

@ -6,11 +6,9 @@
#include "nsPluginArray.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/PluginArrayBinding.h"
#include "mozilla/dom/PluginBinding.h"
#include "nsCharSeparatedTokenizer.h"
#include "nsMimeTypeArray.h"
#include "Navigator.h"
#include "nsIDocShell.h"
@ -68,8 +66,7 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsPluginArray,
mWindow,
mPlugins,
mHiddenPlugins)
mPlugins)
static void
GetPluginMimeTypes(const nsTArray<nsRefPtr<nsPluginElement> >& aPlugins,
@ -89,11 +86,9 @@ operator<(const nsRefPtr<nsMimeType>& lhs, const nsRefPtr<nsMimeType>& rhs)
}
void
nsPluginArray::GetMimeTypes(nsTArray<nsRefPtr<nsMimeType> >& aMimeTypes,
nsTArray<nsRefPtr<nsMimeType> >& aHiddenMimeTypes)
nsPluginArray::GetMimeTypes(nsTArray<nsRefPtr<nsMimeType>>& aMimeTypes)
{
aMimeTypes.Clear();
aHiddenMimeTypes.Clear();
if (!AllowPlugins()) {
return;
@ -102,7 +97,6 @@ nsPluginArray::GetMimeTypes(nsTArray<nsRefPtr<nsMimeType> >& aMimeTypes,
EnsurePlugins();
GetPluginMimeTypes(mPlugins, aMimeTypes);
GetPluginMimeTypes(mHiddenPlugins, aHiddenMimeTypes);
// Alphabetize the enumeration order of non-hidden MIME types to reduce
// fingerprintable entropy based on plugins' installation file times.
@ -146,14 +140,12 @@ nsPluginArray::Refresh(bool aReloadDocuments)
// happens, and therefore the lengths will be in sync only when
// the both arrays contain the same plugin tags (though as
// different types).
uint32_t pluginCount = mPlugins.Length() + mHiddenPlugins.Length();
if (newPluginTags.Length() == pluginCount) {
if (newPluginTags.Length() == mPlugins.Length()) {
return;
}
}
mPlugins.Clear();
mHiddenPlugins.Clear();
nsCOMPtr<nsIDOMNavigator> navigator;
mWindow->GetNavigator(getter_AddRefs(navigator));
@ -225,10 +217,6 @@ nsPluginArray::NamedGetter(const nsAString& aName, bool &aFound)
EnsurePlugins();
nsPluginElement* plugin = FindPlugin(mPlugins, aName);
if (!plugin) {
plugin = FindPlugin(mHiddenPlugins, aName);
}
aFound = (plugin != nullptr);
return plugin;
}
@ -286,28 +274,6 @@ nsPluginArray::AllowPlugins() const
return docShell && docShell->PluginsAllowedInCurrentDoc();
}
static bool
HasStringPrefix(const nsCString& str, const nsACString& prefix) {
return str.Compare(prefix.BeginReading(), false, prefix.Length()) == 0;
}
static bool
IsPluginEnumerable(const nsTArray<nsCString>& enumerableNames,
const nsPluginTag* pluginTag)
{
const nsCString& pluginName = pluginTag->mName;
const uint32_t length = enumerableNames.Length();
for (uint32_t i = 0; i < length; i++) {
const nsCString& name = enumerableNames[i];
if (HasStringPrefix(pluginName, name)) {
return true; // don't hide plugin
}
}
return false; // hide plugin!
}
static bool
operator<(const nsRefPtr<nsPluginElement>& lhs,
const nsRefPtr<nsPluginElement>& rhs)
@ -319,7 +285,7 @@ operator<(const nsRefPtr<nsPluginElement>& lhs,
void
nsPluginArray::EnsurePlugins()
{
if (!mPlugins.IsEmpty() || !mHiddenPlugins.IsEmpty()) {
if (!mPlugins.IsEmpty()) {
// We already have an array of plugin elements.
return;
}
@ -333,36 +299,11 @@ nsPluginArray::EnsurePlugins()
nsTArray<nsRefPtr<nsPluginTag> > pluginTags;
pluginHost->GetPlugins(pluginTags);
nsTArray<nsCString> enumerableNames;
const nsAdoptingCString& enumerableNamesPref =
Preferences::GetCString("plugins.enumerable_names");
bool disablePluginHiding = !enumerableNamesPref ||
enumerableNamesPref.EqualsLiteral("*");
if (!disablePluginHiding) {
nsCCharSeparatedTokenizer tokens(enumerableNamesPref, ',');
while (tokens.hasMoreTokens()) {
const nsCSubstring& token = tokens.nextToken();
if (!token.IsEmpty()) {
enumerableNames.AppendElement(token);
}
}
}
// need to wrap each of these with a nsPluginElement, which is
// scriptable.
for (uint32_t i = 0; i < pluginTags.Length(); ++i) {
nsPluginTag* pluginTag = pluginTags[i];
// Add the plugin to the list of hidden plugins or non-hidden plugins?
nsTArray<nsRefPtr<nsPluginElement> >& pluginArray =
(disablePluginHiding || IsPluginEnumerable(enumerableNames, pluginTag))
? mPlugins
: mHiddenPlugins;
pluginArray.AppendElement(new nsPluginElement(mWindow, pluginTag));
mPlugins.AppendElement(new nsPluginElement(mWindow, pluginTag));
}
// Alphabetize the enumeration order of non-hidden plugins to reduce

View File

@ -40,8 +40,7 @@ public:
void Init();
void Invalidate();
void GetMimeTypes(nsTArray<nsRefPtr<nsMimeType> >& aMimeTypes,
nsTArray<nsRefPtr<nsMimeType> >& aHiddenMimeTypes);
void GetMimeTypes(nsTArray<nsRefPtr<nsMimeType>>& aMimeTypes);
// PluginArray WebIDL methods
@ -61,18 +60,7 @@ private:
void EnsurePlugins();
nsCOMPtr<nsPIDOMWindow> mWindow;
// Many sites check whether a particular plugin is installed by enumerating
// all navigator.plugins, checking each plugin's name. These sites should
// just check navigator.plugins["Popular Plugin Name"] instead. mPlugins
// contains those popular plugins that must be exposed in navigator.plugins
// enumeration to avoid breaking web content.
nsTArray<nsRefPtr<nsPluginElement> > mPlugins;
// mHiddenPlugins contains plugins that can be queried by
// navigator.plugins["Hidden Plugin Name"] but do not need to be exposed in
// navigator.plugins enumeration.
nsTArray<nsRefPtr<nsPluginElement> > mHiddenPlugins;
};
class nsPluginElement final : public nsISupports,

View File

@ -13,7 +13,8 @@
SimpleTest.waitForExplicitFinish();
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_DISABLED, "Second Test Plug-in");
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Java Test Plug-in");
function findPlugin(pluginName) {
for (var i = 0; i < navigator.plugins.length; i++) {
@ -36,38 +37,37 @@
}
function run() {
// Add "Test Plug-in" (but not "Second Test Plug-in") to the list of
// unhidden plugins. This test must modify the "plugins.enumerable_names"
// pref BEFORE accessing the navigator.plugins or navigator.mimeTypes
// arrays because they only read the pref when they first initialize
// their internal arrays!
var prefs = SpecialPowers.Cc["@mozilla.org/preferences-service;1"].getService(SpecialPowers.Ci.nsIPrefBranch);
var defaultEnumerableNamesPref = prefs.getCharPref("plugins.enumerable_names");
SpecialPowers.pushPrefEnv(
{'set': [["plugins.enumerable_names", defaultEnumerableNamesPref + ",Test Plug-in"]]},
finishRun
);
}
function finishRun() {
var pluginElement = document.getElementById("plugin");
is(pluginElement.identifierToStringTest("foo"), "foo", "Should be able to call a function provided by the plugin");
ok(navigator.plugins["Test Plug-in"], "Should have queried a non-hidden plugin named 'Test Plug-in'");
ok(navigator.plugins["Second Test Plug-in"], "Should have queried a hidden plugin named 'Test Plug-in'");
pluginElement = document.getElementById("disabledPlugin");
is(typeof pluginElement.identifierToStringTest, "undefined", "Should NOT be able to call a function on a disabled plugin");
ok(findPlugin("Test Plug-in"), "Should have found a non-hidden plugin named 'Test Plug-in'");
ok(!findPlugin("Second Test Plug-in"), "Should NOT found a hidden plugin named 'Test Plug-in'");
pluginElement = document.getElementById("clickToPlayPlugin");
is(typeof pluginElement.identifierToStringTest, "undefined", "Should NOT be able to call a function on a click-to-play plugin");
ok(navigator.mimeTypes["application/x-test"], "Should have queried a non-hidden MIME type named 'application/x-test'");
ok(navigator.mimeTypes["application/x-second-test"], "Should have queried a MIME type named 'application/x-second-test'");
ok(navigator.plugins["Test Plug-in"], "Should have queried a plugin named 'Test Plug-in'");
ok(!navigator.plugins["Second Test Plug-in"], "Should NOT have queried a disabled plugin named 'Second Test Plug-in'");
ok(navigator.plugins["Java Test Plug-in"], "Should have queried a click-to-play plugin named 'Java Test Plug-in'");
ok(findMimeType("application/x-test"), "Should have found a non-hidden MIME type named 'application/x-test'");
ok(!findMimeType("application/x-second-test"), "Should NOT have found a MIME type named 'application/x-second-test'");
ok(findPlugin("Test Plug-in"), "Should have found a plugin named 'Test Plug-in'");
ok(!findPlugin("Second Test Plug-in"), "Should NOT found a disabled plugin named 'Second Test Plug-in'");
ok(findPlugin("Java Test Plug-in"), "Should have found a click-to-play plugin named 'Java Test Plug-in'");
ok(navigator.mimeTypes["application/x-test"], "Should have queried a MIME type named 'application/x-test'");
ok(!navigator.mimeTypes["application/x-second-test"], "Should NOT have queried a disabled type named 'application/x-second-test'");
ok(navigator.mimeTypes["application/x-java-test"], "Should have queried a click-to-play MIME type named 'application/x-java-test'");
ok(findMimeType("application/x-test"), "Should have found a MIME type named 'application/x-test'");
ok(!findMimeType("application/x-second-test"), "Should NOT have found a disabled MIME type named 'application/x-second-test'");
ok(findMimeType("application/x-java-test"), "Should have found a click-to-play MIME type named 'application/x-java-test'");
SimpleTest.finish();
}
</script>
<object id="plugin" type="application/x-second-test" width=200 height=200></object>
<object id="plugin" type="application/x-test" width=200 height=200></object>
<object id="disabledPlugin" type="application/x-second-test" width=200 height=200></object>
<object id="clickToPlayPlugin" type="application/x-java-test" width=200 height=200></object>
</body>
</html>

View File

@ -2394,14 +2394,6 @@ pref("plugins.load_appdir_plugins", false);
// If true, plugins will be click to play
pref("plugins.click_to_play", false);
// A comma-delimited list of plugin name prefixes matching plugins that will be
// exposed when enumerating navigator.plugins[]. For example, prefix "Shockwave"
// matches both Adobe Flash Player ("Shockwave Flash") and Adobe Shockwave
// Player ("Shockwave for Director"). To hide all plugins from enumeration, use
// the empty string "" to match no plugin names. To allow all plugins to be
// enumerated, use the string "*" to match all plugin names.
pref("plugins.enumerable_names", "*");
// The default value for nsIPluginTag.enabledState (STATE_ENABLED = 2)
pref("plugin.default.state", 2);