Bug 1169459 - remove the loadFromJars/jarURIs prefs, r=Mossop.

This commit is contained in:
Florian Quèze 2015-09-04 11:50:49 +02:00
parent 15be37fc5e
commit 473b4bf762
13 changed files with 152 additions and 274 deletions

View File

@ -356,10 +356,6 @@ pref("browser.helperApps.deleteTempFileOnExit", true);
// search engines URL
pref("browser.search.searchEnginesURL", "https://addons.mozilla.org/%LOCALE%/firefox/search-engines/");
// Tell the search service to load search plugins from the locale JAR
pref("browser.search.loadFromJars", true);
pref("browser.search.jarURIs", "chrome://browser/locale/searchplugins/");
// pointer to the default engine name
pref("browser.search.defaultenginename", "chrome://browser-region/locale/region.properties");

View File

@ -219,7 +219,6 @@ DirectoryProvider::GetFiles(const char *aKey, nsISimpleEnumerator* *aResult)
* - extension search plugin locations (prepended below using
* NS_NewUnionEnumerator)
* - user search plugin locations (profile)
* - app search plugin location (shipped engines)
*/
nsresult rv;
@ -245,7 +244,6 @@ DirectoryProvider::GetFiles(const char *aKey, nsISimpleEnumerator* *aResult)
nsCOMArray<nsIFile> baseFiles;
AppendFileKey(NS_APP_USER_SEARCH_DIR, dirSvc, baseFiles);
AppendFileKey(NS_APP_SEARCH_DIR, dirSvc, baseFiles);
nsCOMPtr<nsISimpleEnumerator> baseEnum;
rv = NS_NewArrayEnumerator(getter_AddRefs(baseEnum), baseFiles);

View File

@ -151,6 +151,7 @@
locale/browser/syncQuota.dtd (%chrome/browser/syncQuota.dtd)
locale/browser/syncQuota.properties (%chrome/browser/syncQuota.properties)
#endif
% resource search-plugins chrome://browser/locale/searchplugins/
locale/browser/searchplugins/list.txt (.deps/generated_@AB_CD@/list.txt)
locale/browser/searchplugins/ (.deps/generated_@AB_CD@/*.xml)
% locale browser-region @AB_CD@ %locale/browser-region/

View File

@ -285,10 +285,6 @@ pref("privacy.trackingprotection.pbmode.enabled", true);
pref("browser.search.suggest.enabled", false);
pref("browser.search.suggest.prompted", false);
// Tell the search service to load search plugins from the locale JAR
pref("browser.search.loadFromJars", true);
pref("browser.search.jarURIs", "chrome://browser/locale/searchplugins/");
// tell the search service that we don't really expose the "current engine"
pref("browser.search.noCurrentEngine", true);

View File

@ -42,6 +42,7 @@
#ifdef NIGHTLY_BUILD
locale/@AB_CD@/browser/webcompatReporter.properties (%chrome/webcompatReporter.properties)
#endif
% resource search-plugins chrome://browser/locale/searchplugins/
# overrides for toolkit l10n, also for en-US
relativesrcdir toolkit/locales:

View File

@ -56,6 +56,11 @@ const NS_APP_USER_SEARCH_DIR = "UsrSrchPlugns";
const NS_APP_SEARCH_DIR = "SrchPlugns";
const NS_APP_USER_PROFILE_50_DIR = "ProfD";
// Loading plugins from NS_APP_SEARCH_DIR is no longer supported.
// Instead, we now load plugins from APP_SEARCH_PREFIX, where a
// list.txt file needs to exist to list available engines.
const APP_SEARCH_PREFIX = "resource://search-plugins/";
// Search engine "locations". If this list is changed, be sure to update
// the engine's _isDefault function accordingly.
const SEARCH_APP_DIR = 1;
@ -920,6 +925,20 @@ function makeURI(aURLSpec, aCharset) {
return null;
}
/**
* Wrapper function for nsIIOService::newChannel2.
* @param url
* The URL string from which to create an nsIChannel.
* @returns an nsIChannel object, or null if the url is invalid.
*/
function makeChannel(url) {
try {
return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
} catch (ex) { }
return null;
}
/**
* Gets a directory from the directory service.
* @param aKey
@ -1732,7 +1751,7 @@ Engine.prototype = {
"Must have URI when calling _initFromURISync!",
Cr.NS_ERROR_UNEXPECTED);
ENSURE_WARN(this._uri.schemeIs("chrome"), "_initFromURISync called for non-chrome URI",
ENSURE_WARN(this._uri.schemeIs("resource"), "_initFromURISync called for non-resource URI",
Cr.NS_ERROR_FAILURE);
LOG("_initFromURISync: Loading engine from: \"" + this._uri.spec + "\".");
@ -3028,6 +3047,11 @@ Engine.prototype = {
let file = this._file;
if (!file) {
let uri = this._uri;
if (uri.schemeIs("resource")) {
uri = makeURI(Services.io.getProtocolHandler("resource")
.QueryInterface(Ci.nsISubstitutingProtocolHandler)
.resolveURI(uri));
}
if (uri.schemeIs("chrome")) {
let packageName = uri.hostPort;
uri = gChromeReg.convertChromeURL(uri);
@ -3612,30 +3636,24 @@ SearchService.prototype = {
cache.directories = {};
cache.visibleDefaultEngines = this._visibleDefaultEngines;
function getParent(engine) {
let getParent = engine => {
if (engine._file)
return engine._file.parent;
let uri = engine._uri;
if (!uri.schemeIs("chrome")) {
LOG("getParent: engine URI must be a chrome URI if it has no file");
if (!uri.schemeIs("resource")) {
LOG("getParent: engine URI must be a resource URI if it has no file");
return null;
}
// use the underlying JAR file, for chrome URIs
try {
uri = gChromeReg.convertChromeURL(uri);
if (uri instanceof Ci.nsINestedURI)
uri = uri.innermostURI;
uri.QueryInterface(Ci.nsIFileURL)
return uri.file;
} catch (ex) {
LOG("getParent: couldn't map chrome:// URI to a file: " + ex)
}
// use the underlying JAR file, for resource URIs
let chan = makeChannel(uri.spec);
if (chan)
return this._convertChannelToFile(chan);
LOG("getParent: couldn't map resource:// URI to a file");
return null;
}
};
for each (let engine in this._engines) {
let parent = getParent(engine);
@ -3687,15 +3705,7 @@ SearchService.prototype = {
cache = this._readCacheFile(cacheFile);
}
let chromeURIs = [], chromeFiles = [];
let loadFromJARs = false;
try {
loadFromJARs = Services.prefs.getDefaultBranch(BROWSER_SEARCH_PREF)
.getBoolPref("loadFromJars");
} catch (ex) {}
if (loadFromJARs)
[chromeFiles, chromeURIs] = this._findJAREngines();
let [chromeFiles, chromeURIs] = this._findJAREngines();
let distDirs = [];
let locations;
@ -3717,8 +3727,6 @@ SearchService.prototype = {
locations = getDir(NS_APP_SEARCH_DIR_LIST, Ci.nsISimpleEnumerator);
while (locations.hasMoreElements()) {
let dir = locations.getNext().QueryInterface(Ci.nsIFile);
if (loadFromJARs && dir.equals(getDir(NS_APP_SEARCH_DIR)))
continue;
if (dir.directoryEntries.hasMoreElements())
otherDirs.push(dir);
}
@ -3785,18 +3793,9 @@ SearchService.prototype = {
cache = yield checkForSyncCompletion(this._asyncReadCacheFile(cacheFilePath));
}
let chromeURIs = [], chromeFiles = [];
let loadFromJARs = false;
try {
loadFromJARs = Services.prefs.getDefaultBranch(BROWSER_SEARCH_PREF)
.getBoolPref("loadFromJars");
} catch (ex) {}
if (loadFromJARs) {
Services.obs.notifyObservers(null, SEARCH_SERVICE_TOPIC, "find-jar-engines");
[chromeFiles, chromeURIs] =
yield checkForSyncCompletion(this._asyncFindJAREngines());
}
Services.obs.notifyObservers(null, SEARCH_SERVICE_TOPIC, "find-jar-engines");
let [chromeFiles, chromeURIs] =
yield checkForSyncCompletion(this._asyncFindJAREngines());
// Get the non-empty distribution directories into distDirs...
let distDirs = [];
@ -3830,12 +3829,6 @@ SearchService.prototype = {
locations = getDir(NS_APP_SEARCH_DIR_LIST, Ci.nsISimpleEnumerator);
while (locations.hasMoreElements()) {
let dir = locations.getNext().QueryInterface(Ci.nsIFile);
// ... but skip the application directory if we are loading from JAR.
// Applications shipping JAR engines don't ship plain text
// engine files anymore.
if (loadFromJARs && dir.equals(getDir(NS_APP_SEARCH_DIR)))
continue;
let iterator = new OS.File.DirectoryIterator(dir.path,
{ winPattern: "*.xml" });
try {
@ -4225,66 +4218,40 @@ SearchService.prototype = {
}.bind(this));
},
_convertChannelToFile: function(chan) {
let fileURI = chan.URI;
while (fileURI instanceof Ci.nsIJARURI)
fileURI = fileURI.JARFile;
fileURI.QueryInterface(Ci.nsIFileURL);
return fileURI.file;
},
_findJAREngines: function SRCH_SVC_findJAREngines() {
LOG("_findJAREngines: looking for engines in JARs")
let rootURIPref = ""
try {
rootURIPref = Services.prefs.getDefaultBranch(BROWSER_SEARCH_PREF)
.getCharPref("jarURIs");
} catch (ex) {}
if (!rootURIPref) {
LOG("_findJAREngines: no JAR URIs were specified");
let chan = makeChannel(APP_SEARCH_PREFIX + "list.txt");
if (!chan) {
LOG("_findJAREngines: " + APP_SEARCH_PREFIX + " isn't registered");
return [[], []];
}
let rootURIs = rootURIPref.split(",");
let uris = [];
let chromeFiles = [];
rootURIs.forEach(root => {
// Find the underlying JAR file for this chrome package (_loadEngines uses
// it to determine whether it needs to invalidate the cache)
let jarPackaging = false;
try {
let chromeURI = gChromeReg.convertChromeURL(makeURI(root));
if (chromeURI instanceof Ci.nsIJARURI) {
let fileURI = chromeURI;
while (fileURI instanceof Ci.nsIJARURI)
fileURI = fileURI.JARFile;
fileURI.QueryInterface(Ci.nsIFileURL);
chromeFiles.push(fileURI.file);
jarPackaging = true;
}
} catch (ex) {
LOG("_findJAREngines: failed to get chromeFile for " + root + ": " + ex);
return;
}
// Read list.txt from the chrome package to find the engines we need to
// load
let listURL = root + "list.txt";
try {
let chan = NetUtil.ioService.newChannelFromURI2(makeURI(listURL),
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
let sis = Cc["@mozilla.org/scriptableinputstream;1"].
createInstance(Ci.nsIScriptableInputStream);
sis.init(chan.open());
this._parseListTxt(sis.read(sis.available()), root, jarPackaging,
chromeFiles, uris);
} catch (ex) {
LOG("_findJAREngines: failed to retrieve list.txt from " + listURL + ": " + ex);
return;
}
});
// Find the underlying JAR file (_loadEngines uses it to determine
// whether it needs to invalidate the cache)
let jarPackaging = false;
if (chan.URI instanceof Ci.nsIJARURI) {
chromeFiles.push(this._convertChannelToFile(chan));
jarPackaging = true;
}
let sis = Cc["@mozilla.org/scriptableinputstream;1"].
createInstance(Ci.nsIScriptableInputStream);
sis.init(chan.open());
this._parseListTxt(sis.read(sis.available()), jarPackaging,
chromeFiles, uris);
return [chromeFiles, uris];
},
@ -4298,65 +4265,46 @@ SearchService.prototype = {
return Task.spawn(function() {
LOG("_asyncFindJAREngines: looking for engines in JARs")
let rootURIPref = "";
try {
rootURIPref = Services.prefs.getDefaultBranch(BROWSER_SEARCH_PREF)
.getCharPref("jarURIs");
} catch (ex) {}
if (!rootURIPref) {
LOG("_asyncFindJAREngines: no JAR URIs were specified");
let listURL = APP_SEARCH_PREFIX + "list.txt";
let chan = makeChannel(listURL);
if (!chan) {
LOG("_asyncFindJAREngines: " + APP_SEARCH_PREFIX + " isn't registered");
throw new Task.Result([[], []]);
}
let rootURIs = rootURIPref.split(",");
let uris = [];
let chromeFiles = [];
for (let root of rootURIs) {
// Find the underlying JAR file for this chrome package (_loadEngines uses
// it to determine whether it needs to invalidate the cache)
let jarPackaging = false;
try {
let chromeURI = gChromeReg.convertChromeURL(makeURI(root));
if (chromeURI instanceof Ci.nsIJARURI) {
let fileURI = chromeURI;
while (fileURI instanceof Ci.nsIJARURI)
fileURI = fileURI.JARFile;
fileURI.QueryInterface(Ci.nsIFileURL);
chromeFiles.push(fileURI.file);
jarPackaging = true;
}
} catch (ex) {
LOG("_asyncFindJAREngines: failed to get chromeFile for " + root + ": " + ex);
return;
}
// Read list.txt from the chrome package to find the engines we need to
// load
let listURL = root + "list.txt";
let deferred = Promise.defer();
let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
createInstance(Ci.nsIXMLHttpRequest);
request.overrideMimeType("text/plain");
request.onload = function(aEvent) {
deferred.resolve(aEvent.target.responseText);
};
request.onerror = function(aEvent) {
LOG("_asyncFindJAREngines: failed to retrieve list.txt from " + listURL);
deferred.resolve("");
};
request.open("GET", NetUtil.newURI(listURL).spec, true);
request.send();
let list = yield deferred.promise;
this._parseListTxt(list, root, jarPackaging, chromeFiles, uris);
// Find the underlying JAR file (_loadEngines uses it to determine
// whether it needs to invalidate the cache)
let jarPackaging = false;
if (chan.URI instanceof Ci.nsIJARURI) {
chromeFiles.push(this._convertChannelToFile(chan));
jarPackaging = true;
}
// Read list.txt to find the engines we need to load.
let deferred = Promise.defer();
let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
createInstance(Ci.nsIXMLHttpRequest);
request.overrideMimeType("text/plain");
request.onload = function(aEvent) {
deferred.resolve(aEvent.target.responseText);
};
request.onerror = function(aEvent) {
LOG("_asyncFindJAREngines: failed to read " + listURL);
deferred.resolve("");
};
request.open("GET", NetUtil.newURI(listURL).spec, true);
request.send();
let list = yield deferred.promise;
this._parseListTxt(list, jarPackaging, chromeFiles, uris);
throw new Task.Result([chromeFiles, uris]);
}.bind(this));
},
_parseListTxt: function SRCH_SVC_parseListTxt(list, root, jarPackaging,
_parseListTxt: function SRCH_SVC_parseListTxt(list, jarPackaging,
chromeFiles, uris) {
let names = list.split("\n").filter(function (n) !!n);
// This maps the names of our built-in engines to a boolean
@ -4405,13 +4353,16 @@ SearchService.prototype = {
}
for (let name of engineNames) {
let uri = root + name + ".xml";
let uri = APP_SEARCH_PREFIX + name + ".xml";
uris.push(uri);
if (!jarPackaging) {
// Flat packaging requires that _loadEngines checks the modification
// time of each engine file.
uri = gChromeReg.convertChromeURL(makeURI(uri));
chromeFiles.push(uri.QueryInterface(Ci.nsIFileURL).file);
let chan = makeChannel(uri);
if (chan)
chromeFiles.push(this._convertChannelToFile(chan));
else
LOG("_findJAREngines: couldn't resolve " + uri);
}
}

View File

@ -74,20 +74,16 @@ function dumpn(text)
/**
* Configure preferences to load engines from
* chrome://testsearchplugin/locale/searchplugins/
* unless the loadFromJars parameter is set to false.
*/
function configureToLoadJarEngines(loadFromJars = true)
function configureToLoadJarEngines()
{
let defaultBranch = Services.prefs.getDefaultBranch(null);
let url = "chrome://testsearchplugin/locale/searchplugins/";
defaultBranch.setCharPref("browser.search.jarURIs", url);
defaultBranch.setBoolPref("browser.search.loadFromJars", loadFromJars);
// Give the pref a user set value that is the opposite of the default,
// to ensure user set values are ignored.
Services.prefs.setBoolPref("browser.search.loadFromJars", !loadFromJars)
let resProt = Services.io.getProtocolHandler("resource")
.QueryInterface(Ci.nsIResProtocolHandler);
resProt.setSubstitution("search-plugins",
Services.io.newURI(url, null, null));
// Ensure a test engine exists in the app dir anyway.
let dir = Services.dirsvc.get(NS_APP_SEARCH_DIR, Ci.nsIFile);

View File

@ -1,30 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function run_test() {
do_test_pending();
removeMetadata();
removeCacheFile();
do_load_manifest("data/chrome.manifest");
configureToLoadJarEngines(false);
do_check_false(Services.search.isInitialized);
Services.search.init(function search_initialized(aStatus) {
do_check_true(Components.isSuccessCode(aStatus));
do_check_true(Services.search.isInitialized);
// test engine from dir is loaded.
let engine = Services.search.getEngineByName("TestEngineApp");
do_check_neq(engine, null);
// test jar engine is not loaded.
engine = Services.search.getEngineByName("bug645970");
do_check_eq(engine, null);
do_test_finished();
});
}

View File

@ -57,58 +57,46 @@ function run_test() {
// Add the application's built-in plugin locations to the cache so it won't be ignored.
let filesToIgnore = []
let defaultBranch = Services.prefs.getDefaultBranch(BROWSER_SEARCH_PREF);
let loadFromJARs = false;
try {
loadFromJARs = defaultBranch.getBoolPref("loadFromJars");
} catch (ex) {}
let chan = NetUtil.ioService.newChannel2("resource://search-plugins/list.txt",
null, // aOriginCharset
null, // aBaseURI
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
let visibleDefaultEngines = [];
if (!loadFromJARs) {
filesToIgnore.push(getDir(NS_APP_SEARCH_DIR));
let sis = Cc["@mozilla.org/scriptableinputstream;1"].
createInstance(Ci.nsIScriptableInputStream);
sis.init(chan.open());
let list = sis.read(sis.available());
let names = list.split("\n").filter(n => !!n);
for (let name of names) {
if (name.endsWith(":hidden"))
continue;
visibleDefaultEngines.push(name);
}
let chromeURI = chan.URI;
if (chromeURI instanceof Ci.nsIJARURI) {
// JAR packaging, we only need the parent jar file.
let fileURI = chromeURI; // flat packaging
while (fileURI instanceof Ci.nsIJARURI)
fileURI = fileURI.JARFile;
fileURI.QueryInterface(Ci.nsIFileURL);
filesToIgnore.push(fileURI.file);
} else {
let rootURIPref = defaultBranch.getCharPref("jarURIs");
let rootURIs = rootURIPref.split(",");
for (let root of rootURIs) {
let visibleEnginesForRoot = [];
let listURL = root + "list.txt";
let chan = NetUtil.ioService.newChannelFromURI2(makeURI(listURL),
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
let sis = Cc["@mozilla.org/scriptableinputstream;1"].
createInstance(Ci.nsIScriptableInputStream);
sis.init(chan.open());
let list = sis.read(sis.available());
let names = list.split("\n").filter(n => !!n);
for (let name of names) {
if (name.endsWith(":hidden"))
continue;
visibleEnginesForRoot.push(name);
}
let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"].
getService(Ci.nsIChromeRegistry);
let chromeURI = chromeReg.convertChromeURL(makeURI(root));
if (chromeURI instanceof Ci.nsIJARURI) {
// JAR packaging, we only need the parent jar file.
let fileURI = chromeURI; // flat packaging
while (fileURI instanceof Ci.nsIJARURI)
fileURI = fileURI.JARFile;
fileURI.QueryInterface(Ci.nsIFileURL);
filesToIgnore.push(fileURI.file);
} else {
// flat packaging, we need to find each .xml file.
for (let name of visibleEnginesForRoot) {
let uri = chromeReg.convertChromeURL(makeURI(root + name + ".xml"));
filesToIgnore.push(uri.QueryInterface(Ci.nsIFileURL).file);
}
}
visibleDefaultEngines = visibleDefaultEngines.concat(visibleEnginesForRoot);
// flat packaging, we need to find each .xml file.
for (let name of names) {
let url = "resource://search-plugins/" + name + ".xml";
let chan = NetUtil.ioService.newChannel2(url,
null, // aOriginCharset
null, // aBaseURI
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
filesToIgnore.push(chan.URI.QueryInterface(Ci.nsIFileURL).file);
}
}

View File

@ -1,23 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function run_test() {
removeMetadata();
removeCacheFile();
do_load_manifest("data/chrome.manifest");
configureToLoadJarEngines(false);
do_check_false(Services.search.isInitialized);
// test engine from dir is loaded.
let engine = Services.search.getEngineByName("TestEngineApp");
do_check_neq(engine, null);
do_check_true(Services.search.isInitialized);
// test jar engine is not loaded.
engine = Services.search.getEngineByName("bug645970");
do_check_eq(engine, null);
}

View File

@ -61,7 +61,6 @@ support-files =
[test_serialize_file.js]
[test_searchSuggest.js]
[test_async.js]
[test_async_app.js]
[test_async_addon.js]
tags = addons
[test_async_addon_no_override.js]
@ -69,7 +68,6 @@ tags = addons
[test_async_distribution.js]
[test_async_profile_engine.js]
[test_sync.js]
[test_sync_app.js]
[test_sync_addon.js]
tags = addons
[test_sync_addon_no_override.js]

View File

@ -1036,9 +1036,11 @@ add_task(function* test_defaultSearchEngine() {
// Load the engines definitions from a custom JAR file: that's needed so that
// the search provider reports an engine identifier.
let defaultBranch = Services.prefs.getDefaultBranch(null);
defaultBranch.setCharPref("browser.search.jarURIs", "chrome://testsearchplugin/locale/searchplugins/");
defaultBranch.setBoolPref("browser.search.loadFromJars", true);
let url = "chrome://testsearchplugin/locale/searchplugins/";
let resProt = Services.io.getProtocolHandler("resource")
.QueryInterface(Ci.nsIResProtocolHandler);
resProt.setSubstitution("search-plugins",
Services.io.newURI(url, null, null));
// Initialize the search service.
yield new Promise(resolve => Services.search.init(resolve));

View File

@ -7,6 +7,7 @@
#include "nsAppFileLocationProvider.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsDirectoryServiceDefs.h"
#include "nsEnumeratorUtils.h"
#include "nsIAtom.h"
#include "nsIFile.h"
#include "nsString.h"
@ -583,7 +584,7 @@ nsAppFileLocationProvider::GetFiles(const char* aProp,
rv = NS_OK;
}
if (!nsCRT::strcmp(aProp, NS_APP_SEARCH_DIR_LIST)) {
static const char* keys[] = { nullptr, NS_APP_SEARCH_DIR, NS_APP_USER_SEARCH_DIR, nullptr };
static const char* keys[] = { nullptr, NS_APP_USER_SEARCH_DIR, nullptr };
if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_SEARCH_ENGINE_PATH"))) {
static const char nullstr = 0;
keys[0] = &nullstr;
@ -592,6 +593,9 @@ nsAppFileLocationProvider::GetFiles(const char* aProp,
NS_ADDREF(*aResult);
rv = NS_OK;
}
if (!strcmp(aProp, NS_APP_DISTRIBUTION_SEARCH_DIR_LIST)) {
return NS_NewEmptyEnumerator(aResult);
}
return rv;
}