Bug 1156566 - Don't add invalid GMPs to GMPService in GMPProvider. r=spohl

This commit is contained in:
Chris Pearce 2015-05-15 11:50:40 +12:00
Родитель a224ee9100
Коммит 1d7b493a55
3 изменённых файлов: 110 добавлений и 10 удалений

Просмотреть файл

@ -89,8 +89,8 @@ this.GMPPrefs = {
KEY_CERTS_BRANCH: "media.gmp-manager.certs.",
KEY_PROVIDER_ENABLED: "media.gmp-provider.enabled",
KEY_LOG_BASE: "media.gmp.log.",
KEY_LOGGING_LEVEL: this.KEY_LOG_BASE + "level",
KEY_LOGGING_DUMP: this.KEY_LOG_BASE + "dump",
KEY_LOGGING_LEVEL: "media.gmp.log.level",
KEY_LOGGING_DUMP: "media.gmp.log.dump",
/**
* Obtains the specified preference in relation to the specified plugin.

Просмотреть файл

@ -447,6 +447,43 @@ GMPWrapper.prototype = {
}
return this._updateTask;
},
_arePluginFilesOnDisk: function () {
let fileExists = function(aGmpPath, aFileName) {
let f = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
let path = OS.Path.join(aGmpPath, aFileName);
f.initWithPath(path);
return f.exists();
};
// Determine the name of the GMP dynamic library; it differs on every
// platform. Note: we can't use Services.appInfo.OS here, as that's
// "XPCShell" in our tests.
let isWindows = ("@mozilla.org/windows-registry-key;1" in Cc);
let isOSX = ("nsILocalFileMac" in Ci);
let isLinux = ("@mozilla.org/gnome-gconf-service;1" in Cc);
let libName = "";
let id = this._plugin.id;
if (isWindows) {
libName = id.substring(4) + ".dll";
} else if (isOSX) {
libName = "lib" + id.substring(4) + ".dylib";
} else if (isLinux) {
libName = id.substring(4) + ".so";
} else {
this._info.error("_arePluginFilesOnDisk - unsupported platform.");
return false;
}
return fileExists(this.gmpPath, libName) &&
fileExists(this.gmpPath, id.substring(4) + ".info");
},
validate: function() {
return !this.isInstalled ||
this._arePluginFilesOnDisk();
},
};
let GMPProvider = {
@ -472,6 +509,12 @@ let GMPProvider = {
gmpPath);
if (gmpPath && isEnabled) {
if (!wrapper.validate()) {
this._log.info("startup - gmp " + plugin.id +
" missing lib and/or info files, uninstalling");
wrapper.uninstallPlugin();
continue;
}
this._log.info("startup - adding gmp directory " + gmpPath);
try {
gmpService.addPluginDirectory(gmpPath);

Просмотреть файл

@ -9,6 +9,9 @@ let GMPScope = Cu.import("resource://gre/modules/addons/GMPProvider.jsm");
XPCOMUtils.defineLazyGetter(this, "pluginsBundle",
() => Services.strings.createBundle("chrome://global/locale/plugins.properties"));
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
let gMockAddons = new Map();
let gMockEmeAddons = new Map();
@ -216,11 +219,41 @@ add_task(function* test_autoUpdatePrefPersistance() {
}
});
function createMockPluginFilesIfNeeded(aFile, aPluginId) {
function createFile(aFileName) {
let f = aFile.clone();
f.append(aFileName);
if (!f.exists()) {
f.create(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
}
};
// Note: we can't use Services.appInfo.OS, as that's "XPCShell" in our tests.
let isWindows = ("@mozilla.org/windows-registry-key;1" in Components.classes);
let isOSX = ("nsILocalFileMac" in Components.interfaces);
let isLinux = ("@mozilla.org/gnome-gconf-service;1" in Components.classes);
let libName = "";
if (isWindows) {
libName = aPluginId.substring(4) + ".dll";
} else if (isOSX) {
libName = "lib" + aPluginId.substring(4) + ".dylib";
} else if (isLinux) {
libName = aPluginId.substring(4) + ".so";
} else {
// FAIL!
return;
}
createFile(libName);
createFile(aPluginId.substring(4) + ".info");
}
add_task(function* test_pluginRegistration() {
const TEST_VERSION = "1.2.3.4";
let profD = do_get_profile();
for (let addon of gMockAddons.values()) {
let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
let file = profD.clone();
file.append(addon.id);
file.append(TEST_VERSION);
@ -229,17 +262,41 @@ add_task(function* test_pluginRegistration() {
let clearPaths = () => { addedPaths = []; removedPaths = []; }
let MockGMPService = {
addPluginDirectory: path => addedPaths.push(path),
removePluginDirectory: path => removedPaths.push(path),
removeAndDeletePluginDirectory: path => removedPaths.push(path),
addPluginDirectory: path => {
if (!addedPaths.includes(path)) {
addedPaths.push(path);
}
},
removePluginDirectory: path => {
if (!removedPaths.includes(path)) {
removedPaths.push(path);
}
},
removeAndDeletePluginDirectory: path => {
if (!removedPaths.includes(path)) {
removedPaths.push(path);
}
},
};
GMPScope.gmpService = MockGMPService;
gPrefs.setBoolPref(gGetKey(GMPScope.GMPPrefs.KEY_PLUGIN_ENABLED, addon.id), true);
// Check that the plugin gets registered after startup.
// Test that plugin registration fails if the plugin dynamic library and
// info files are not present.
gPrefs.setCharPref(gGetKey(GMPScope.GMPPrefs.KEY_PLUGIN_VERSION, addon.id),
TEST_VERSION);
TEST_VERSION);
clearPaths();
yield promiseRestartManager();
Assert.equal(addedPaths.indexOf(file.path), -1);
Assert.deepEqual(removedPaths, [file.path]);
// Create dummy GMP library/info files, and test that plugin registration
// succeeds during startup, now that we've added GMP info/lib files.
createMockPluginFilesIfNeeded(file, addon.id);
gPrefs.setCharPref(gGetKey(GMPScope.GMPPrefs.KEY_PLUGIN_VERSION, addon.id),
TEST_VERSION);
clearPaths();
yield promiseRestartManager();
Assert.notEqual(addedPaths.indexOf(file.path), -1);
@ -259,7 +316,7 @@ add_task(function* test_pluginRegistration() {
// Changing the pref mid-session should cause unregistration and registration.
gPrefs.setCharPref(gGetKey(GMPScope.GMPPrefs.KEY_PLUGIN_VERSION, addon.id),
TEST_VERSION);
TEST_VERSION);
clearPaths();
const TEST_VERSION_2 = "5.6.7.8";
let file2 = Services.dirsvc.get("ProfD", Ci.nsIFile);
@ -272,7 +329,7 @@ add_task(function* test_pluginRegistration() {
// Disabling the plugin should cause unregistration.
gPrefs.setCharPref(gGetKey(GMPScope.GMPPrefs.KEY_PLUGIN_VERSION, addon.id),
TEST_VERSION);
TEST_VERSION);
clearPaths();
gPrefs.setBoolPref(gGetKey(GMPScope.GMPPrefs.KEY_PLUGIN_ENABLED, addon.id), false);
Assert.deepEqual(addedPaths, []);