Backed out 2 changesets (bug 1214058) for xpcshell bustage

Backed out changeset 90e625ac70b2 (bug 1214058)
Backed out changeset a4d5d63a03ef (bug 1214058)
This commit is contained in:
Wes Kocher 2015-11-03 16:06:23 -08:00
Родитель 110d21abaa
Коммит 7a3e94be61
20 изменённых файлов: 2491 добавлений и 3657 удалений

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

@ -4402,7 +4402,6 @@ pref("xpinstall.whitelist.required", true);
pref("xpinstall.signatures.required", false); pref("xpinstall.signatures.required", false);
pref("extensions.alwaysUnpack", false); pref("extensions.alwaysUnpack", false);
pref("extensions.minCompatiblePlatformVersion", "2.0"); pref("extensions.minCompatiblePlatformVersion", "2.0");
pref("extensions.webExtensionsMinPlatformVersion", "42.0a1");
pref("network.buffer.cache.count", 24); pref("network.buffer.cache.count", 24);
pref("network.buffer.cache.size", 32768); pref("network.buffer.cache.size", 32768);

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

@ -42,8 +42,6 @@ const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
const PREF_SELECTED_LOCALE = "general.useragent.locale"; const PREF_SELECTED_LOCALE = "general.useragent.locale";
const UNKNOWN_XPCOM_ABI = "unknownABI"; const UNKNOWN_XPCOM_ABI = "unknownABI";
const PREF_MIN_WEBEXT_PLATFORM_VERSION = "extensions.webExtensionsMinPlatformVersion";
const UPDATE_REQUEST_VERSION = 2; const UPDATE_REQUEST_VERSION = 2;
const CATEGORY_UPDATE_PARAMS = "extension-update-params"; const CATEGORY_UPDATE_PARAMS = "extension-update-params";
@ -665,7 +663,6 @@ var gCheckUpdateSecurity = gCheckUpdateSecurityDefault;
var gUpdateEnabled = true; var gUpdateEnabled = true;
var gAutoUpdateDefault = true; var gAutoUpdateDefault = true;
var gHotfixID = null; var gHotfixID = null;
var gWebExtensionsMinPlatformVersion = null;
var gShutdownBarrier = null; var gShutdownBarrier = null;
var gRepoShutdownState = ""; var gRepoShutdownState = "";
var gShutdownInProgress = false; var gShutdownInProgress = false;
@ -950,11 +947,6 @@ var AddonManagerInternal = {
} catch (e) {} } catch (e) {}
Services.prefs.addObserver(PREF_EM_HOTFIX_ID, this, false); Services.prefs.addObserver(PREF_EM_HOTFIX_ID, this, false);
try {
gWebExtensionsMinPlatformVersion = Services.prefs.getCharPref(PREF_MIN_WEBEXT_PLATFORM_VERSION);
} catch (e) {}
Services.prefs.addObserver(PREF_MIN_WEBEXT_PLATFORM_VERSION, this, false);
let defaultProvidersEnabled = true; let defaultProvidersEnabled = true;
try { try {
defaultProvidersEnabled = Services.prefs.getBoolPref(PREF_DEFAULT_PROVIDERS_ENABLED); defaultProvidersEnabled = Services.prefs.getBoolPref(PREF_DEFAULT_PROVIDERS_ENABLED);
@ -1385,10 +1377,6 @@ var AddonManagerInternal = {
} }
break; break;
} }
case PREF_MIN_WEBEXT_PLATFORM_VERSION: {
gWebExtensionsMinPlatformVersion = Services.prefs.getCharPref(PREF_MIN_WEBEXT_PLATFORM_VERSION);
break;
}
} }
}, },
@ -2906,10 +2894,6 @@ this.AddonManagerPrivate = {
safeCall(listener.onUpdateFinished.bind(listener), addon); safeCall(listener.onUpdateFinished.bind(listener), addon);
} }
}, },
get webExtensionsMinPlatformVersion() {
return gWebExtensionsMinPlatformVersion;
},
}; };
/** /**

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

@ -31,8 +31,6 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager", XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm"); "resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate",
"resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonRepository", XPCOMUtils.defineLazyModuleGetter(this, "AddonRepository",
"resource://gre/modules/addons/AddonRepository.jsm"); "resource://gre/modules/addons/AddonRepository.jsm");
@ -219,48 +217,6 @@ RDFSerializer.prototype = {
} }
} }
/**
* Sanitizes the update URL in an update item, as returned by
* parseRDFManifest and parseJSONManifest. Ensures that:
*
* - The URL is secure, or secured by a strong enough hash.
* - The security principal of the update manifest has permission to
* load the URL.
*
* @param aUpdate
* The update item to sanitize.
* @param aRequest
* The XMLHttpRequest used to load the manifest.
* @param aHashPattern
* The regular expression used to validate the update hash.
* @param aHashString
* The human-readable string specifying which hash functions
* are accepted.
*/
function sanitizeUpdateURL(aUpdate, aRequest, aHashPattern, aHashString) {
if (aUpdate.updateURL) {
let scriptSecurity = Services.scriptSecurityManager;
let principal = scriptSecurity.getChannelURIPrincipal(aRequest.channel);
try {
// This logs an error on failure, so no need to log it a second time
scriptSecurity.checkLoadURIStrWithPrincipal(principal, aUpdate.updateURL,
scriptSecurity.DISALLOW_SCRIPT);
} catch (e) {
delete aUpdate.updateURL;
return;
}
if (AddonManager.checkUpdateSecurity &&
!aUpdate.updateURL.startsWith("https:") &&
!aHashPattern.test(aUpdate.updateHash)) {
logger.warn(`Update link ${aUpdate.updateURL} is not secure and is not verified ` +
`by a strong enough hash (needs to be ${aHashString}).`);
delete aUpdate.updateURL;
delete aUpdate.updateHash;
}
}
}
/** /**
* Parses an RDF style update manifest into an array of update objects. * Parses an RDF style update manifest into an array of update objects.
* *
@ -270,17 +226,10 @@ function sanitizeUpdateURL(aUpdate, aRequest, aHashPattern, aHashString) {
* An optional update key for the add-on * An optional update key for the add-on
* @param aRequest * @param aRequest
* The XMLHttpRequest that has retrieved the update manifest * The XMLHttpRequest that has retrieved the update manifest
* @param aManifestData
* The pre-parsed manifest, as a bare XML DOM document
* @return an array of update objects * @return an array of update objects
* @throws if the update manifest is invalid in any way * @throws if the update manifest is invalid in any way
*/ */
function parseRDFManifest(aId, aUpdateKey, aRequest, aManifestData) { function parseRDFManifest(aId, aUpdateKey, aRequest) {
if (aManifestData.documentElement.namespaceURI != PREFIX_NS_RDF) {
throw Components.Exception("Update manifest had an unrecognised namespace: " + xml.documentElement.namespaceURI);
return;
}
function EM_R(aProp) { function EM_R(aProp) {
return gRDF.GetResource(PREFIX_NS_EM + aProp); return gRDF.GetResource(PREFIX_NS_EM + aProp);
} }
@ -417,136 +366,20 @@ function parseRDFManifest(aId, aUpdateKey, aRequest, aManifestData) {
targetApplications: [appEntry] targetApplications: [appEntry]
}; };
// The JSON update protocol requires an SHA-2 hash. RDF still if (result.updateURL && AddonManager.checkUpdateSecurity &&
// supports SHA-1, for compatibility reasons. result.updateURL.substring(0, 6) != "https:" &&
sanitizeUpdateURL(result, aRequest, /^sha/, "sha1 or stronger"); (!result.updateHash || result.updateHash.substring(0, 3) != "sha")) {
logger.warn("updateLink " + result.updateURL + " is not secure and is not verified" +
" by a strong enough hash (needs to be sha1 or stronger).");
delete result.updateURL;
delete result.updateHash;
}
results.push(result); results.push(result);
} }
} }
return results; return results;
} }
/**
* Parses an JSON update manifest into an array of update objects.
*
* @param aId
* The ID of the add-on being checked for updates
* @param aUpdateKey
* An optional update key for the add-on
* @param aRequest
* The XMLHttpRequest that has retrieved the update manifest
* @param aManifestData
* The pre-parsed manifest, as a JSON object tree
* @return an array of update objects
* @throws if the update manifest is invalid in any way
*/
function parseJSONManifest(aId, aUpdateKey, aRequest, aManifestData) {
if (aUpdateKey)
throw Components.Exception("Update keys are not supported for JSON update manifests");
let TYPE_CHECK = {
"array": val => Array.isArray(val),
"object": val => val && typeof val == "object" && !Array.isArray(val),
};
function getProperty(aObj, aProperty, aType, aDefault = undefined) {
if (!(aProperty in aObj))
return aDefault;
let value = aObj[aProperty];
let matchesType = aType in TYPE_CHECK ? TYPE_CHECK[aType](value) : typeof value == aType;
if (!matchesType)
throw Components.Exception(`Update manifest property '${aProperty}' has incorrect type (expected ${aType})`);
return value;
}
function getRequiredProperty(aObj, aProperty, aType) {
let value = getProperty(aObj, aProperty, aType);
if (value === undefined)
throw Components.Exception(`Update manifest is missing a required ${aProperty} property.`);
return value;
}
let manifest = aManifestData;
if (!TYPE_CHECK["object"](manifest))
throw Components.Exception("Root element of update manifest must be a JSON object literal");
// The set of add-ons this manifest has updates for
let addons = getRequiredProperty(manifest, "addons", "object");
// The entry for this particular add-on
let addon = getProperty(addons, aId, "object");
// A missing entry doesn't count as a failure, just as no avialable update
// information
if (!addon) {
logger.warn("Update manifest did not contain an entry for " + aId);
return [];
}
// The list of available updates
let updates = getProperty(addon, "updates", "array", []);
let results = [];
for (let update of updates) {
let version = getRequiredProperty(update, "version", "string");
logger.debug(`Found an update entry for ${aId} version ${version}`);
let applications = getProperty(update, "applications", "object",
{ gecko: {} });
// "gecko" is currently the only supported application entry. If
// it's missing, skip this update.
if (!("gecko" in applications))
continue;
let app = getProperty(applications, "gecko", "object");
let appEntry = {
id: TOOLKIT_ID,
minVersion: getProperty(app, "strict_min_version", "string",
AddonManagerPrivate.webExtensionsMinPlatformVersion),
maxVersion: "*",
};
let result = {
id: aId,
version: version,
multiprocessCompatible: getProperty(update, "multiprocess_compatible", "boolean", true),
updateURL: getProperty(update, "update_link", "string"),
updateHash: getProperty(update, "update_hash", "string"),
updateInfoURL: getProperty(update, "update_info_url", "string"),
strictCompatibility: false,
targetApplications: [appEntry],
};
if ("strict_max_version" in app) {
if ("advisory_max_version" in app) {
logger.warn("Ignoring 'advisory_max_version' update manifest property for " +
aId + " property since 'strict_max_version' also present");
}
appEntry.maxVersion = getProperty(app, "strict_max_version", "string");
result.strictCompatibility = appEntry.maxVersion != "*";
} else if ("advisory_max_version" in app) {
appEntry.maxVersion = getProperty(app, "advisory_max_version", "string");
}
// The JSON update protocol requires an SHA-2 hash. RDF still
// supports SHA-1, for compatibility reasons.
sanitizeUpdateURL(result, aRequest, /^sha(256|512):/, "sha256 or sha512");
results.push(result);
}
return results;
}
/** /**
* Starts downloading an update manifest and then passes it to an appropriate * Starts downloading an update manifest and then passes it to an appropriate
* parser to convert to an array of update objects * parser to convert to an array of update objects
@ -582,7 +415,7 @@ function UpdateParser(aId, aUpdateKey, aUrl, aObserver) {
this.request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE; this.request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
// Prevent the request from writing to cache. // Prevent the request from writing to cache.
this.request.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING; this.request.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
this.request.overrideMimeType("text/plain"); this.request.overrideMimeType("text/xml");
this.request.setRequestHeader("Moz-XPI-Update", "1", true); this.request.setRequestHeader("Moz-XPI-Update", "1", true);
this.request.timeout = TIMEOUT; this.request.timeout = TIMEOUT;
var self = this; var self = this;
@ -641,50 +474,41 @@ UpdateParser.prototype = {
return; return;
} }
// Detect the manifest type by first attempting to parse it as let xml = request.responseXML;
// JSON, and falling back to parsing it as XML if that fails. if (!xml || xml.documentElement.namespaceURI == XMLURI_PARSE_ERROR) {
let parser; logger.warn("Update manifest was not valid XML");
try {
try {
let json = JSON.parse(request.responseText);
parser = () => parseJSONManifest(this.id, this.updateKey, request, json);
} catch (e if e instanceof SyntaxError) {
let domParser = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);
let xml = domParser.parseFromString(request.responseText, "text/xml");
if (xml.documentElement.namespaceURI == XMLURI_PARSE_ERROR)
throw new Error("Update manifest was not valid XML or JSON");
parser = () => parseRDFManifest(this.id, this.updateKey, request, xml);
}
} catch (e) {
logger.warn("onUpdateCheckComplete failed to determine manifest type");
this.notifyError(AddonUpdateChecker.ERROR_UNKNOWN_FORMAT);
return;
}
let results;
try {
results = parser();
}
catch (e) {
logger.warn("onUpdateCheckComplete failed to parse update manifest", e);
this.notifyError(AddonUpdateChecker.ERROR_PARSE_ERROR); this.notifyError(AddonUpdateChecker.ERROR_PARSE_ERROR);
return; return;
} }
if ("onUpdateCheckComplete" in this.observer) { // We currently only know about RDF update manifests
if (xml.documentElement.namespaceURI == PREFIX_NS_RDF) {
let results = null;
try { try {
this.observer.onUpdateCheckComplete(results); results = parseRDFManifest(this.id, this.updateKey, request);
} }
catch (e) { catch (e) {
logger.warn("onUpdateCheckComplete notification failed", e); logger.warn("onUpdateCheckComplete failed to parse RDF manifest", e);
this.notifyError(AddonUpdateChecker.ERROR_PARSE_ERROR);
return;
} }
if ("onUpdateCheckComplete" in this.observer) {
try {
this.observer.onUpdateCheckComplete(results);
}
catch (e) {
logger.warn("onUpdateCheckComplete notification failed", e);
}
}
else {
logger.warn("onUpdateCheckComplete may not properly cancel", new Error("stack marker"));
}
return;
} }
else {
logger.warn("onUpdateCheckComplete may not properly cancel", new Error("stack marker")); logger.warn("Update manifest had an unrecognised namespace: " + xml.documentElement.namespaceURI);
} this.notifyError(AddonUpdateChecker.ERROR_UNKNOWN_FORMAT);
}, },
/** /**

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

@ -906,7 +906,7 @@ function loadManifestFromWebManifest(aStream) {
addon.targetApplications = [{ addon.targetApplications = [{
id: TOOLKIT_ID, id: TOOLKIT_ID,
minVersion: AddonManagerPrivate.webExtensionsMinPlatformVersion, minVersion: "42a1",
maxVersion: "*", maxVersion: "*",
}]; }];

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

@ -1,215 +0,0 @@
{
"addons": {
"addon1@tests.mozilla.org": {
"updates": [
{
"version": "1.0",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_min_version": "1"
}
}
},
{
"version": "1.0",
"applications": {
"gecko": {
"strict_min_version": "2",
"strict_min_version": "2"
}
}
},
{
"version": "2.0",
"update_link": "http://localhost:%PORT%/addons/test_update.xpi",
"update_info_url": "http://example.com/updateInfo.xhtml",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_min_version": "1"
}
}
}
]
},
"addon2@tests.mozilla.org": {
"updates": [
{
"version": "1.0",
"applications": {
"gecko": {
"strict_min_version": "0",
"advisory_max_version": "1"
}
}
}
]
},
"addon2@tests.mozilla.org": {
"updates": [
{
"version": "1.0",
"applications": {
"gecko": {
"strict_min_version": "0",
"advisory_max_version": "1"
}
}
}
]
},
"addon3@tests.mozilla.org": {
"updates": [
{
"version": "1.0",
"applications": {
"gecko": {
"strict_min_version": "3",
"advisory_max_version": "3"
}
}
}
]
},
"addon4@tests.mozilla.org": {
"updates": [
{
"version": "5.0",
"applications": {
"gecko": {
"strict_min_version": "0",
"advisory_max_version": "0"
}
}
}
]
},
"addon7@tests.mozilla.org": {
"updates": [
{
"version": "1.0",
"applications": {
"gecko": {
"strict_min_version": "0",
"advisory_max_version": "1"
}
}
}
]
},
"addon8@tests.mozilla.org": {
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:%PORT%/addons/test_update8.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"advisory_max_version": "1"
}
}
}
]
},
"addon9@tests.mozilla.org": {
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:%PORT%/addons/test_update9_2.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"advisory_max_version": "1"
}
}
},
{
"_comment_": "Incompatible when strict compatibility is enabled",
"version": "3.0",
"update_link": "http://localhost:%PORT%/addons/test_update9_3.xpi",
"applications": {
"gecko": {
"strict_min_version": "0.9",
"advisory_max_version": "0.9"
}
}
},
{
"_comment_": "Incompatible due to compatibility override",
"version": "4.0",
"update_link": "http://localhost:%PORT%/addons/test_update9_4.xpi",
"applications": {
"gecko": {
"strict_min_version": "0.9",
"advisory_max_version": "0.9"
}
}
},
{
"_comment_": "Addon for future version of app",
"version": "4.0",
"update_link": "http://localhost:%PORT%/addons/test_update9_5.xpi",
"applications": {
"gecko": {
"strict_min_version": "5",
"advisory_max_version": "6"
}
}
}
]
},
"addon10@tests.mozilla.org": {
"updates": [
{
"version": "1.0",
"update_link": "http://localhost:%PORT%/addons/test_update10.xpi",
"applications": {
"gecko": {
"strict_min_version": "0.1",
"advisory_max_version": "0.4"
}
}
}
]
},
"addon11@tests.mozilla.org": {
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:%PORT%/addons/test_update11.xpi",
"applications": {
"gecko": {
"strict_min_version": "0.1",
"strict_max_version": "0.2"
}
}
}
]
},
"addon12@tests.mozilla.org": {
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:%PORT%/addons/test_update12.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"advisory_max_version": "1"
}
}
}
]
}
}
}

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

@ -1,327 +0,0 @@
{
"addons": {
"updatecheck1@tests.mozilla.org": {
"updates": [
{
"version": "1.0",
"update_link": "https://localhost:4444/addons/test1.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_max_version": "1"
}
}
},
{
"_comment_": "This update is incompatible and so should not be considered a valid update",
"version": "2.0",
"update_link": "https://localhost:4444/addons/test2.xpi",
"applications": {
"gecko": {
"strict_min_version": "2",
"strict_max_version": "2"
}
}
},
{
"version": "3.0",
"update_link": "https://localhost:4444/addons/test3.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_max_version": "1"
}
}
},
{
"version": "2.0",
"update_link": "https://localhost:4444/addons/test2.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_max_version": "2"
}
}
},
{
"_comment_": "This update is incompatible and so should not be considered a valid update",
"version": "4.0",
"update_link": "https://localhost:4444/addons/test4.xpi",
"applications": {
"gecko": {
"strict_min_version": "2",
"strict_max_version": "2"
}
}
}
]
},
"test_bug378216_5@tests.mozilla.org": {
"_comment_": "An update which expects a signature. It will fail since signatures are ",
"_comment_": "supported in this format.",
"_comment_": "The updateLink will also be ignored since it is not secure and there ",
"_comment_": "is no updateHash.",
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:4444/broken.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_max_version": "1"
}
}
}
]
},
"test_bug378216_5@tests.mozilla.org": {
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:4444/broken.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_max_version": "1"
}
}
}
]
},
"test_bug378216_7@tests.mozilla.org": {
"_comment_": "An update which expects a signature. It will fail since signatures are ",
"_comment_": "supported in this format.",
"_comment_": "The updateLink will also be ignored since it is not secure ",
"_comment_": "and there is no updateHash.",
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:4444/broken.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_max_version": "2"
}
}
}
]
},
"test_bug378216_8@tests.mozilla.org": {
"_comment_": "The updateLink will be ignored since it is not secure and ",
"_comment_": "there is no updateHash.",
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:4444/broken.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_max_version": "1"
}
}
}
]
},
"test_bug378216_9@tests.mozilla.org": {
"_comment_": "The updateLink will used since there is an updateHash to verify it.",
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:4444/broken.xpi",
"update_hash": "sha256:78fc1d2887eda35b4ad2e3a0b60120ca271ce6e6",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_max_version": "1"
}
}
}
]
},
"test_bug378216_10@tests.mozilla.org": {
"_comment_": "The updateLink will used since it is a secure URL.",
"updates": [
{
"version": "2.0",
"update_link": "https://localhost:4444/broken.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_max_version": "1"
}
}
}
]
},
"test_bug378216_11@tests.mozilla.org": {
"_comment_": "The updateLink will used since it is a secure URL.",
"updates": [
{
"version": "2.0",
"update_link": "https://localhost:4444/broken.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_max_version": "1"
}
}
}
]
},
"test_bug378216_12@tests.mozilla.org": {
"_comment_": "The updateLink will not be used since the updateHash ",
"_comment_": "verifying it is not strong enough.",
"updates": [
{
"version": "2.0",
"update_link": "http://localhost:4444/broken.xpi",
"update_hash": "sha1:78fc1d2887eda35b4ad2e3a0b60120ca271ce6e6",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_max_version": "1"
}
}
}
]
},
"test_bug378216_13@tests.mozilla.org": {
"_comment_": "An update with a weak hash. The updateLink will used since it is ",
"_comment_": "a secure URL.",
"updates": [
{
"version": "2.0",
"update_link": "https://localhost:4444/broken.xpi",
"update_hash": "sha1:78fc1d2887eda35b4ad2e3a0b60120ca271ce6e6",
"applications": {
"gecko": {
"strict_min_version": "1",
"strict_max_version": "1"
}
}
}
]
},
"_comment_": "There should be no information present for test_bug378216_14",
"test_bug378216_15@tests.mozilla.org": {
"_comment_": "Invalid update JSON",
"updates": "foo"
},
"ignore-compat@tests.mozilla.org": {
"_comment_": "Various updates available - one is not compatible, but compatibility checking is disabled",
"updates": [
{
"version": "1.0",
"update_link": "https://localhost:4444/addons/test1.xpi",
"applications": {
"gecko": {
"strict_min_version": "0.1",
"advisory_max_version": "0.2"
}
}
},
{
"version": "2.0",
"update_link": "https://localhost:4444/addons/test2.xpi",
"applications": {
"gecko": {
"strict_min_version": "0.5",
"advisory_max_version": "0.6"
}
}
},
{
"_comment_": "Update for future app versions - should never be compatible",
"version": "3.0",
"update_link": "https://localhost:4444/addons/test3.xpi",
"applications": {
"gecko": {
"strict_min_version": "2",
"advisory_max_version": "3"
}
}
}
]
},
"compat-override@tests.mozilla.org": {
"_comment_": "Various updates available - one is not compatible, but compatibility checking is disabled",
"updates": [
{
"_comment_": "Has compatibility override, but it doesn't match this app version",
"version": "1.0",
"update_link": "https://localhost:4444/addons/test1.xpi",
"applications": {
"gecko": {
"strict_min_version": "0.1",
"advisory_max_version": "0.2"
}
}
},
{
"_comment_": "Has compatibility override, so is incompaible",
"version": "2.0",
"update_link": "https://localhost:4444/addons/test2.xpi",
"applications": {
"gecko": {
"strict_min_version": "0.5",
"advisory_max_version": "0.6"
}
}
},
{
"_comment_": "Update for future app versions - should never be compatible",
"version": "3.0",
"update_link": "https://localhost:4444/addons/test3.xpi",
"applications": {
"gecko": {
"strict_min_version": "2",
"advisory_max_version": "3"
}
}
}
]
},
"compat-strict-optin@tests.mozilla.org": {
"_comment_": "Opt-in to strict compatibility checking",
"updates": [
{
"version": "1.0",
"update_link": "https://localhost:4444/addons/test1.xpi",
"_comment_": "strictCompatibility: true",
"applications": {
"gecko": {
"strict_min_version": "0.1",
"strict_max_version": "0.2"
}
}
}
]
}
}
}

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

@ -236,7 +236,7 @@
A90eF5zy</em:signature> A90eF5zy</em:signature>
</RDF:Description> </RDF:Description>
<!-- An update with a valid signature. The updateLink will not be used since the <!-- An update with a valid signature. The updateLink will used since the
updateHash verifying it is not strong enough. --> updateHash verifying it is not strong enough. -->
<RDF:Description about="urn:mozilla:extension:test_bug378216_12@tests.mozilla.org"> <RDF:Description about="urn:mozilla:extension:test_bug378216_12@tests.mozilla.org">
<em:updates> <em:updates>

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

@ -1542,7 +1542,7 @@ if ("nsIWindowsRegKey" in AM_Ci) {
* This is a mock nsIWindowsRegistry implementation. It only implements the * This is a mock nsIWindowsRegistry implementation. It only implements the
* methods that the extension manager requires. * methods that the extension manager requires.
*/ */
var MockWindowsRegKey = function MockWindowsRegKey() { function MockWindowsRegKey() {
} }
MockWindowsRegKey.prototype = { MockWindowsRegKey.prototype = {
@ -1723,30 +1723,6 @@ do_register_cleanup(function addon_cleanup() {
} catch (e) {} } catch (e) {}
}); });
/**
* Creates a new HttpServer for testing, and begins listening on the
* specified port. Automatically shuts down the server when the test
* unit ends.
*
* @param port
* The port to listen on. If omitted, listen on a random
* port. The latter is the preferred behavior.
*
* @return HttpServer
*/
function createHttpServer(port = -1) {
let server = new HttpServer();
server.start(port);
do_register_cleanup(() => {
return new Promise(resolve => {
server.stop(resolve);
});
});
return server;
}
/** /**
* Handler function that responds with the interpolated * Handler function that responds with the interpolated
* static file associated to the URL specified by request.path. * static file associated to the URL specified by request.path.
@ -1920,89 +1896,19 @@ function promiseAddonByID(aId) {
*/ */
function promiseFindAddonUpdates(addon, reason = AddonManager.UPDATE_WHEN_PERIODIC_UPDATE) { function promiseFindAddonUpdates(addon, reason = AddonManager.UPDATE_WHEN_PERIODIC_UPDATE) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let result = {};
addon.findUpdates({ addon.findUpdates({
onNoCompatibilityUpdateAvailable: function(addon2) { install: null,
if ("compatibilityUpdate" in result) {
do_throw("Saw multiple compatibility update events"); onUpdateAvailable: function(addon, install) {
} this.install = install;
equal(addon, addon2);
addon.compatibilityUpdate = false;
}, },
onCompatibilityUpdateAvailable: function(addon2) { onUpdateFinished: function(addon, error) {
if ("compatibilityUpdate" in result) { if (error == AddonManager.UPDATE_STATUS_NO_ERROR)
do_throw("Saw multiple compatibility update events"); resolve(this.install);
} else
equal(addon, addon2); reject(error);
addon.compatibilityUpdate = true;
},
onNoUpdateAvailable: function(addon2) {
if ("updateAvailable" in result) {
do_throw("Saw multiple update available events");
}
equal(addon, addon2);
result.updateAvailable = false;
},
onUpdateAvailable: function(addon2, install) {
if ("updateAvailable" in result) {
do_throw("Saw multiple update available events");
}
equal(addon, addon2);
result.updateAvailable = install;
},
onUpdateFinished: function(addon2, error) {
equal(addon, addon2);
if (error == AddonManager.UPDATE_STATUS_NO_ERROR) {
resolve(result);
} else {
result.error = error;
reject(result);
}
} }
}, reason); }, reason);
}); });
} }
/**
* Monitors console output for the duration of a task, and returns a promise
* which resolves to a tuple containing a list of all console messages
* generated during the task's execution, and the result of the task itself.
*
* @param {function} aTask
* The task to run while monitoring console output. May be
* either a generator function, per Task.jsm, or an ordinary
* function which returns promose.
* @return {Promise<[Array<nsIConsoleMessage>, *]>}
*/
var promiseConsoleOutput = Task.async(function*(aTask) {
const DONE = "=== xpcshell test console listener done ===";
let listener, messages = [];
let awaitListener = new Promise(resolve => {
listener = msg => {
if (msg == DONE) {
resolve();
} else {
msg instanceof Components.interfaces.nsIScriptError;
messages.push(msg);
}
}
});
Services.console.registerListener(listener);
try {
let result = yield aTask();
Services.console.logStringMessage(DONE);
yield awaitListener;
return { messages, result };
}
finally {
Services.console.unregisterListener(listener);
}
});

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

@ -505,8 +505,9 @@ add_task(function* setup() {
yield promiseInstallAllFiles(ADDON_FILES); yield promiseInstallAllFiles(ADDON_FILES);
yield promiseRestartManager(); yield promiseRestartManager();
gServer = createHttpServer(PORT); gServer = new HttpServer();
gServer.registerDirectory("/data/", do_get_file("data")); gServer.registerDirectory("/data/", do_get_file("data"));
gServer.start(PORT);
}); });
// Tests AddonRepository.cacheEnabled // Tests AddonRepository.cacheEnabled
@ -703,3 +704,7 @@ add_task(function* run_test_17() {
let aAddons = yield promiseAddonsByIDs(ADDON_IDS); let aAddons = yield promiseAddonsByIDs(ADDON_IDS);
check_results(aAddons, WITH_EXTENSION_CACHE); check_results(aAddons, WITH_EXTENSION_CACHE);
}); });
add_task(function* end_test() {
yield new Promise((resolve, reject) => gServer.stop(resolve));
});

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

@ -41,7 +41,8 @@ Cu.import("resource://testing-common/MockRegistrar.jsm");
Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false) Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false)
Cu.import("resource://testing-common/httpd.js"); Cu.import("resource://testing-common/httpd.js");
var testserver = createHttpServer(); var testserver = new HttpServer();
testserver.start(-1);
gPort = testserver.identity.primaryPort; gPort = testserver.identity.primaryPort;
// register static files with server and interpolate port numbers in them // register static files with server and interpolate port numbers in them
@ -1304,3 +1305,9 @@ add_task(function* run_local_install_test() {
check_addon(h, "1.0", false, false, Ci.nsIBlocklistService.STATE_BLOCKED); check_addon(h, "1.0", false, false, Ci.nsIBlocklistService.STATE_BLOCKED);
check_addon(r, "1.0", false, false, Ci.nsIBlocklistService.STATE_BLOCKED); check_addon(r, "1.0", false, false, Ci.nsIBlocklistService.STATE_BLOCKED);
}); });
add_task(function* shutdown_httpserver() {
yield new Promise((resolve, reject) => {
testserver.stop(resolve);
});
});

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

@ -296,9 +296,10 @@ add_task(function* init() {
}, profileDir); }, profileDir);
// Create and configure the HTTP server. // Create and configure the HTTP server.
testserver = createHttpServer(4444); testserver = new HttpServer();
testserver.registerDirectory("/data/", do_get_file("data")); testserver.registerDirectory("/data/", do_get_file("data"));
testserver.registerDirectory("/addons/", do_get_file("addons")); testserver.registerDirectory("/addons/", do_get_file("addons"));
testserver.start(4444);
startupManager(); startupManager();
@ -463,3 +464,13 @@ add_task(function* run_test_6() {
"override1x2-1x3@tests.mozilla.org"]); "override1x2-1x3@tests.mozilla.org"]);
check_state_v1_2(addons); check_state_v1_2(addons);
}); });
add_task(function* cleanup() {
return new Promise((resolve, reject) => {
testserver.stop(resolve);
});
});
function run_test() {
run_next_test();
}

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

@ -16,47 +16,65 @@ function run_test() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2"); createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
// Create and configure the HTTP server. // Create and configure the HTTP server.
testserver = createHttpServer(); testserver = new HttpServer();
testserver.registerDirectory("/data/", do_get_file("data")); testserver.registerDirectory("/data/", do_get_file("data"));
testserver.registerDirectory("/addons/", do_get_file("addons")); testserver.registerDirectory("/addons/", do_get_file("addons"));
testserver.start(-1);
gPort = testserver.identity.primaryPort; gPort = testserver.identity.primaryPort;
run_next_test(); writeInstallRDFForExtension({
id: "addon1@tests.mozilla.org",
version: "1.0",
updateURL: "http://localhost:" + gPort + "/data/test_missing.rdf",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}],
name: "Test Addon 1",
}, profileDir);
startupManager();
do_test_pending();
run_test_1();
}
function end_test() {
testserver.stop(do_test_finished);
} }
// Verify that an update check returns the correct errors. // Verify that an update check returns the correct errors.
add_task(function* () { function run_test_1() {
for (let manifestType of ["rdf", "json"]) { AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
writeInstallRDFForExtension({ do_check_neq(a1, null);
id: "addon1@tests.mozilla.org", do_check_eq(a1.version, "1.0");
version: "1.0",
updateURL: `http://localhost:${gPort}/data/test_missing.${manifestType}`,
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}],
name: "Test Addon 1",
bootstrap: "true",
}, profileDir);
yield promiseRestartManager(); let sawCompat = false;
let sawUpdate = false;
a1.findUpdates({
onNoCompatibilityUpdateAvailable: function(addon) {
sawCompat = true;
},
let addon = yield promiseAddonByID("addon1@tests.mozilla.org"); onCompatibilityUpdateAvailable: function(addon) {
do_throw("Should not have seen a compatibility update");
},
ok(addon); onNoUpdateAvailable: function(addon) {
ok(addon.updateURL.endsWith(manifestType)); sawUpdate = true;
equal(addon.version, "1.0"); },
// We're expecting an error, so resolve when the promise is rejected. onUpdateAvailable: function(addon, install) {
let update = yield promiseFindAddonUpdates(addon, AddonManager.UPDATE_WHEN_USER_REQUESTED) do_throw("Should not have seen an update");
.catch(Promise.resolve); },
ok(!update.compatibilityUpdate, "not expecting a compatibility update"); onUpdateFinished: function(addon, error) {
ok(!update.updateAvailable, "not expecting a compatibility update"); do_check_true(sawCompat);
do_check_true(sawUpdate);
equal(update.error, AddonManager.UPDATE_STATUS_DOWNLOAD_ERROR); do_check_eq(error, AddonManager.UPDATE_STATUS_DOWNLOAD_ERROR);
end_test();
addon.uninstall(); }
} }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
}); });
}

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

@ -1,373 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
"use strict";
// This verifies that AddonUpdateChecker works correctly for JSON
// update manifests, particularly for behavior which does not
// cleanly overlap with RDF manifests.
const TOOLKIT_ID = "toolkit@mozilla.org";
const TOOLKIT_MINVERSION = "42.0a1";
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "42.0a2", "42.0a2");
Components.utils.import("resource://gre/modules/addons/AddonUpdateChecker.jsm");
Components.utils.import("resource://testing-common/httpd.js");
let testserver = createHttpServer();
gPort = testserver.identity.primaryPort;
let gUpdateManifests = {};
function mapManifest(aPath, aManifestData) {
gUpdateManifests[aPath] = aManifestData;
testserver.registerPathHandler(aPath, serveManifest);
}
function serveManifest(request, response) {
let manifest = gUpdateManifests[request.path];
response.setHeader("Content-Type", manifest.contentType, false);
response.write(manifest.data);
}
const extensionsDir = gProfD.clone();
extensionsDir.append("extensions");
function checkUpdates(aData) {
// Registers JSON update manifest for it with the testing server,
// checks for updates, and yields the list of updates on
// success.
let extension = aData.manifestExtension || "json";
let path = `/updates/${aData.id}.${extension}`;
let updateUrl = `http://localhost:${gPort}${path}`
let addonData = {};
if ("updates" in aData)
addonData.updates = aData.updates;
let manifestJSON = {
"addons": {
[aData.id]: addonData
}
};
mapManifest(path.replace(/\?.*/, ""),
{ data: JSON.stringify(manifestJSON),
contentType: aData.contentType || "application/json" });
return new Promise((resolve, reject) => {
AddonUpdateChecker.checkForUpdates(aData.id, aData.updateKey, updateUrl, {
onUpdateCheckComplete: resolve,
onUpdateCheckError: function(status) {
reject(new Error("Update check failed with status " + status));
}
});
});
}
add_task(function* test_default_values() {
// Checks that the appropriate defaults are used for omitted values.
startupManager();
let updates = yield checkUpdates({
id: "updatecheck-defaults@tests.mozilla.org",
version: "0.1",
updates: [{
version: "0.2"
}]
});
equal(updates.length, 1);
let update = updates[0];
equal(update.targetApplications.length, 1);
let targetApp = update.targetApplications[0];
equal(targetApp.id, TOOLKIT_ID);
equal(targetApp.minVersion, TOOLKIT_MINVERSION);
equal(targetApp.maxVersion, "*");
equal(update.version, "0.2");
equal(update.multiprocessCompatible, true, "multiprocess_compatible flag");
equal(update.strictCompatibility, false, "inferred strictConpatibility flag");
equal(update.updateURL, null, "updateURL");
equal(update.updateHash, null, "updateHash");
equal(update.updateInfoURL, null, "updateInfoURL");
// If there's no applications property, we default to using one
// containing "gecko". If there is an applications property, but
// it doesn't contain "gecko", the update is skipped.
updates = yield checkUpdates({
id: "updatecheck-defaults@tests.mozilla.org",
version: "0.1",
updates: [{
version: "0.2",
applications: { "foo": {} }
}]
});
equal(updates.length, 0);
// Updates property is also optional. No updates, but also no error.
updates = yield checkUpdates({
id: "updatecheck-defaults@tests.mozilla.org",
version: "0.1",
});
equal(updates.length, 0);
});
add_task(function* test_explicit_values() {
// Checks that the appropriate explicit values are used when
// provided.
let updates = yield checkUpdates({
id: "updatecheck-explicit@tests.mozilla.org",
version: "0.1",
updates: [{
version: "0.2",
update_link: "https://example.com/foo.xpi",
update_hash: "sha256:0",
update_info_url: "https://example.com/update_info.html",
multiprocess_compatible: false,
applications: {
gecko: {
strict_min_version: "42.0a2.xpcshell",
strict_max_version: "43.xpcshell"
}
}
}]
});
equal(updates.length, 1);
let update = updates[0];
equal(update.targetApplications.length, 1);
let targetApp = update.targetApplications[0];
equal(targetApp.id, TOOLKIT_ID);
equal(targetApp.minVersion, "42.0a2.xpcshell");
equal(targetApp.maxVersion, "43.xpcshell");
equal(update.version, "0.2");
equal(update.multiprocessCompatible, false, "multiprocess_compatible flag");
equal(update.strictCompatibility, true, "inferred strictCompatibility flag");
equal(update.updateURL, "https://example.com/foo.xpi", "updateURL");
equal(update.updateHash, "sha256:0", "updateHash");
equal(update.updateInfoURL, "https://example.com/update_info.html", "updateInfoURL");
});
add_task(function* test_secure_hashes() {
// Checks that only secure hash functions are accepted for
// non-secure update URLs.
let hashFunctions = ["sha512",
"sha256",
"sha1",
"md5",
"md4",
"xxx"];
let updateItems = hashFunctions.map((hash, idx) => ({
version: `0.${idx}`,
update_link: `http://localhost:${gPort}/updates/${idx}-${hash}.xpi`,
update_hash: `${hash}:08ac852190ecd81f40a514ea9299fe9143d9ab5e296b97e73fb2a314de49648a`,
}));
let { messages, result: updates } = yield promiseConsoleOutput(() => {
return checkUpdates({
id: "updatecheck-hashes@tests.mozilla.org",
version: "0.1",
updates: updateItems
});
});
equal(updates.length, hashFunctions.length);
updates = updates.filter(update => update.updateHash || update.updateURL);
equal(updates.length, 2, "expected number of update hashes were accepted");
ok(updates[0].updateHash.startsWith("sha512:"), "sha512 hash is present");
ok(updates[0].updateURL);
ok(updates[1].updateHash.startsWith("sha256:"), "sha256 hash is present");
ok(updates[1].updateURL);
messages = messages.filter(msg => /Update link.*not secure.*strong enough hash \(needs to be sha256 or sha512\)/.test(msg.message));
equal(messages.length, hashFunctions.length - 2, "insecure hashes generated the expected warning");
});
add_task(function* test_strict_compat() {
// Checks that strict compatibility is enabled for strict max
// versions other than "*", but not for advisory max versions.
// Also, ensure that strict max versions take precedence over
// advisory versions.
let { messages, result: updates } = yield promiseConsoleOutput(() => {
return checkUpdates({
id: "updatecheck-strict@tests.mozilla.org",
version: "0.1",
updates: [
{ version: "0.2",
applications: { gecko: { strict_max_version: "*" } } },
{ version: "0.3",
applications: { gecko: { strict_max_version: "43" } } },
{ version: "0.4",
applications: { gecko: { advisory_max_version: "43" } } },
{ version: "0.5",
applications: { gecko: { advisory_max_version: "43",
strict_max_version: "44" } } },
]
});
});
equal(updates.length, 4, "all update items accepted");
equal(updates[0].targetApplications[0].maxVersion, "*");
equal(updates[0].strictCompatibility, false);
equal(updates[1].targetApplications[0].maxVersion, "43");
equal(updates[1].strictCompatibility, true);
equal(updates[2].targetApplications[0].maxVersion, "43");
equal(updates[2].strictCompatibility, false);
equal(updates[3].targetApplications[0].maxVersion, "44");
equal(updates[3].strictCompatibility, true);
messages = messages.filter(msg => /Ignoring 'advisory_max_version'.*'strict_max_version' also present/.test(msg.message));
equal(messages.length, 1, "mix of advisory_max_version and strict_max_version generated the expected warning");
});
add_task(function* test_update_url_security() {
// Checks that update links to privileged URLs are not accepted.
let { messages, result: updates } = yield promiseConsoleOutput(() => {
return checkUpdates({
id: "updatecheck-security@tests.mozilla.org",
version: "0.1",
updates: [
{ version: "0.2",
update_link: "chrome://browser/content/browser.xul",
update_hash: "sha256:08ac852190ecd81f40a514ea9299fe9143d9ab5e296b97e73fb2a314de49648a" },
{ version: "0.3",
update_link: "http://example.com/update.xpi",
update_hash: "sha256:18ac852190ecd81f40a514ea9299fe9143d9ab5e296b97e73fb2a314de49648a" },
]
});
});
equal(updates.length, 2, "both updates were processed");
equal(updates[0].updateURL, null, "privileged update URL was removed");
equal(updates[1].updateURL, "http://example.com/update.xpi", "safe update URL was accepted");
messages = messages.filter(msg => /http:\/\/localhost.*\/updates\/.*may not load or link to chrome:/.test(msg.message));
equal(messages.length, 1, "privileged upate URL generated the expected console message");
});
add_task(function* test_no_update_key() {
// Checks that updates fail when an update key has been specified.
let { messages } = yield promiseConsoleOutput(function* () {
yield Assert.rejects(
checkUpdates({
id: "updatecheck-updatekey@tests.mozilla.org",
version: "0.1",
updateKey: "ayzzx=",
updates: [
{ version: "0.2" },
{ version: "0.3" },
]
}),
null, "updated expected to fail");
});
messages = messages.filter(msg => /Update keys are not supported for JSON update manifests/.test(msg.message));
equal(messages.length, 1, "got expected update-key-unsupported error");
});
add_task(function* test_type_detection() {
// Checks that JSON update manifests are detected correctly
// regardless of extension or MIME type.
let tests = [
{ contentType: "application/json",
extension: "json",
valid: true },
{ contentType: "application/json",
extension: "php",
valid: true },
{ contentType: "text/plain",
extension: "json",
valid: true },
{ contentType: "application/octet-stream",
extension: "json",
valid: true },
{ contentType: "text/plain",
extension: "json?foo=bar",
valid: true },
{ contentType: "text/plain",
extension: "php",
valid: true },
{ contentType: "text/plain",
extension: "rdf",
valid: true },
{ contentType: "application/json",
extension: "rdf",
valid: true },
{ contentType: "text/xml",
extension: "json",
valid: true },
{ contentType: "application/rdf+xml",
extension: "json",
valid: true },
];
for (let [i, test] of tests.entries()) {
let { messages } = yield promiseConsoleOutput(function *() {
let id = `updatecheck-typedetection-${i}@tests.mozilla.org`;
let updates;
try {
updates = yield checkUpdates({
id: id,
version: "0.1",
contentType: test.contentType,
manifestExtension: test.extension,
updates: [{ version: "0.2" }]
});
} catch (e) {
ok(!test.valid, "update manifest correctly detected as RDF");
return;
}
ok(test.valid, "update manifest correctly detected as JSON");
equal(updates.length, 1, "correct number of updates");
equal(updates[0].id, id, "update is for correct extension");
});
if (test.valid) {
// Make sure we don't get any XML parsing errors from the
// XMLHttpRequest machinery.
ok(!messages.some(msg => /not well-formed/.test(msg.message)),
"expect XMLHttpRequest not to attempt XML parsing");
}
messages = messages.filter(msg => /Update manifest was not valid XML/.test(msg.message));
equal(messages.length, !test.valid, "expected number of XML parsing errors");
}
});

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

@ -69,9 +69,10 @@ add_task(function* checkFirstMetadata() {
Services.prefs.setBoolPref(PREF_EM_SHOW_MISMATCH_UI, true); Services.prefs.setBoolPref(PREF_EM_SHOW_MISMATCH_UI, true);
// Create and configure the HTTP server. // Create and configure the HTTP server.
testserver = createHttpServer(); testserver = new HttpServer();
testserver.registerDirectory("/data/", do_get_file("data")); testserver.registerDirectory("/data/", do_get_file("data"));
testserver.registerDirectory("/addons/", do_get_file("addons")); testserver.registerDirectory("/addons/", do_get_file("addons"));
testserver.start(-1);
gPort = testserver.identity.primaryPort; gPort = testserver.identity.primaryPort;
const BASE_URL = "http://localhost:" + gPort; const BASE_URL = "http://localhost:" + gPort;
const GETADDONS_RESULTS = BASE_URL + "/data/test_AddonRepository_cache.xml"; const GETADDONS_RESULTS = BASE_URL + "/data/test_AddonRepository_cache.xml";
@ -158,3 +159,15 @@ add_task(function* upgrade_young_pref_lastupdate() {
yield promiseRestartManager("2"); yield promiseRestartManager("2");
do_check_false(WindowWatcher.expected); do_check_false(WindowWatcher.expected);
}); });
add_task(function* cleanup() {
return new Promise((resolve, reject) => {
testserver.stop(resolve);
});
});
function run_test() {
run_next_test();
}

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

@ -16,7 +16,8 @@ const WORKING = "signed_bootstrap_1.xpi";
const ID = "test@tests.mozilla.org"; const ID = "test@tests.mozilla.org";
Components.utils.import("resource://testing-common/httpd.js"); Components.utils.import("resource://testing-common/httpd.js");
var gServer = createHttpServer(4444); var gServer = new HttpServer();
gServer.start(4444);
// Creates an add-on with a broken signature by changing an existing file // Creates an add-on with a broken signature by changing an existing file
function createBrokenAddonModify(file) { function createBrokenAddonModify(file) {
@ -136,8 +137,7 @@ function* test_update_broken(file, expectedError) {
serveUpdateRDF(file.leafName); serveUpdateRDF(file.leafName);
let addon = yield promiseAddonByID(ID); let addon = yield promiseAddonByID(ID);
let update = yield promiseFindAddonUpdates(addon); let install = yield promiseFindAddonUpdates(addon);
let install = update.updateAvailable;
yield promiseCompleteAllInstalls([install]); yield promiseCompleteAllInstalls([install]);
do_check_eq(install.state, AddonManager.STATE_DOWNLOAD_FAILED); do_check_eq(install.state, AddonManager.STATE_DOWNLOAD_FAILED);
@ -158,8 +158,7 @@ function* test_update_working(file, expectedSignedState) {
serveUpdateRDF(file.leafName); serveUpdateRDF(file.leafName);
let addon = yield promiseAddonByID(ID); let addon = yield promiseAddonByID(ID);
let update = yield promiseFindAddonUpdates(addon); let install = yield promiseFindAddonUpdates(addon);
let install = update.updateAvailable;
yield promiseCompleteAllInstalls([install]); yield promiseCompleteAllInstalls([install]);
do_check_eq(install.state, AddonManager.STATE_INSTALLED); do_check_eq(install.state, AddonManager.STATE_INSTALLED);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -9,13 +9,12 @@ const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
// The test extension uses an insecure update url. // The test extension uses an insecure update url.
Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false); Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false);
Components.utils.import("resource://testing-common/httpd.js"); Components.utils.import("resource://testing-common/httpd.js");
var testserver = createHttpServer(); var testserver = new HttpServer();
testserver.start(-1);
gPort = testserver.identity.primaryPort; gPort = testserver.identity.primaryPort;
mapFile("/data/test_update.rdf", testserver); mapFile("/data/test_update.rdf", testserver);
mapFile("/data/test_update.json", testserver);
mapFile("/data/test_update.xml", testserver); mapFile("/data/test_update.xml", testserver);
testserver.registerDirectory("/addons/", do_get_file("addons")); testserver.registerDirectory("/addons/", do_get_file("addons"));
@ -23,86 +22,77 @@ const profileDir = gProfD.clone();
profileDir.append("extensions"); profileDir.append("extensions");
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1"); function run_test() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
let testParams = [ run_test_1();
{ updateFile: "test_update.rdf", }
appId: "xpcshell@tests.mozilla.org" },
{ updateFile: "test_update.json",
appId: "toolkit@mozilla.org" },
];
for (let test of testParams) { // Test that the update check correctly observes the
let { updateFile, appId } = test; // extensions.strictCompatibility pref and compatibility overrides.
function run_test_1() {
writeInstallRDFForExtension({
id: "addon9@tests.mozilla.org",
version: "1.0",
updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "0.1",
maxVersion: "0.2"
}],
name: "Test Addon 9",
}, profileDir);
restartManager();
// Test that the update check correctly observes the AddonManager.addInstallListener({
// extensions.strictCompatibility pref and compatibility overrides. onNewInstall: function(aInstall) {
add_test(function () { if (aInstall.existingAddon.id != "addon9@tests.mozilla.org")
writeInstallRDFForExtension({ do_throw("Saw unexpected onNewInstall for " + aInstall.existingAddon.id);
id: "addon9@tests.mozilla.org", do_check_eq(aInstall.version, "4.0");
version: "1.0", },
updateURL: "http://localhost:" + gPort + "/data/" + updateFile, onDownloadFailed: function(aInstall) {
targetApplications: [{ do_execute_soon(run_test_2);
id: appId, }
minVersion: "0.1",
maxVersion: "0.2"
}],
name: "Test Addon 9",
}, profileDir);
restartManager();
AddonManager.addInstallListener({
onNewInstall: function(aInstall) {
if (aInstall.existingAddon.id != "addon9@tests.mozilla.org")
do_throw("Saw unexpected onNewInstall for " + aInstall.existingAddon.id);
do_check_eq(aInstall.version, "4.0");
},
onDownloadFailed: function(aInstall) {
run_next_test();
}
});
Services.prefs.setCharPref(PREF_GETADDONS_BYIDS_PERFORMANCE,
"http://localhost:" + gPort + "/data/" + updateFile);
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
AddonManagerInternal.backgroundUpdateCheck();
}); });
// Test that the update check correctly observes when an addon opts-in to Services.prefs.setCharPref(PREF_GETADDONS_BYIDS_PERFORMANCE,
// strict compatibility checking. "http://localhost:" + gPort + "/data/test_update.xml");
add_test(function () { Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
writeInstallRDFForExtension({
id: "addon11@tests.mozilla.org",
version: "1.0",
updateURL: "http://localhost:" + gPort + "/data/" + updateFile,
targetApplications: [{
id: appId,
minVersion: "0.1",
maxVersion: "0.2"
}],
name: "Test Addon 11",
}, profileDir);
restartManager(); AddonManagerInternal.backgroundUpdateCheck();
}
AddonManager.getAddonByID("addon11@tests.mozilla.org", function(a11) { // Test that the update check correctly observes when an addon opts-in to
do_check_neq(a11, null); // strict compatibility checking.
function run_test_2() {
writeInstallRDFForExtension({
id: "addon11@tests.mozilla.org",
version: "1.0",
updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "0.1",
maxVersion: "0.2"
}],
name: "Test Addon 11",
}, profileDir);
restartManager();
a11.findUpdates({ AddonManager.getAddonByID("addon11@tests.mozilla.org", function(a11) {
onCompatibilityUpdateAvailable: function() { do_check_neq(a11, null);
do_throw("Should not have seen compatibility information");
},
onUpdateAvailable: function() { a11.findUpdates({
do_throw("Should not have seen an available update"); onCompatibilityUpdateAvailable: function() {
}, do_throw("Should have not have seen compatibility information");
},
onUpdateFinished: function() { onNoUpdateAvailable: function() {
run_next_test(); do_throw("Should have seen an available update");
} },
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
}); onUpdateFinished: function() {
end_test();
}
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
}); });
} }

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -7,46 +7,51 @@
Components.utils.import("resource://gre/modules/addons/AddonUpdateChecker.jsm"); Components.utils.import("resource://gre/modules/addons/AddonUpdateChecker.jsm");
Components.utils.import("resource://testing-common/httpd.js"); Components.utils.import("resource://testing-common/httpd.js");
var testserver;
var testserver = createHttpServer(4444);
testserver.registerDirectory("/data/", do_get_file("data"));
function checkUpdates(aId, aUpdateKey, aUpdateFile) {
return new Promise((resolve, reject) => {
AddonUpdateChecker.checkForUpdates(aId, aUpdateKey, `http://localhost:4444/data/${aUpdateFile}`, {
onUpdateCheckComplete: resolve,
onUpdateCheckError: function(status) {
let error = new Error("Update check failed with status " + status);
error.status = status;
reject(error);
}
});
});
}
function run_test() { function run_test() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1"); createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
run_next_test(); // Create and configure the HTTP server.
testserver = new HttpServer();
testserver.registerDirectory("/data/", do_get_file("data"));
testserver.start(4444);
do_test_pending();
run_test_1();
}
function end_test() {
testserver.stop(do_test_finished);
} }
// Test that a basic update check returns the expected available updates // Test that a basic update check returns the expected available updates
add_task(function* () { function run_test_1() {
for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) { AddonUpdateChecker.checkForUpdates("updatecheck1@tests.mozilla.org", null,
let updates = yield checkUpdates("updatecheck1@tests.mozilla.org", null, file); "http://localhost:4444/data/test_updatecheck.rdf", {
onUpdateCheckComplete: function(updates) {
check_test_1(updates);
},
equal(updates.length, 5); onUpdateCheckError: function(status) {
let update = AddonUpdateChecker.getNewestCompatibleUpdate(updates); do_throw("Update check failed with status " + status);
notEqual(update, null); }
equal(update.version, "3.0"); });
update = AddonUpdateChecker.getCompatibilityUpdate(updates, "2"); }
notEqual(update, null);
equal(update.version, "2.0"); function check_test_1(updates) {
equal(update.targetApplications[0].minVersion, "1"); do_check_eq(updates.length, 5);
equal(update.targetApplications[0].maxVersion, "2"); let update = AddonUpdateChecker.getNewestCompatibleUpdate(updates);
} do_check_neq(update, null);
}); do_check_eq(update.version, 3);
update = AddonUpdateChecker.getCompatibilityUpdate(updates, "2");
do_check_neq(update, null);
do_check_eq(update.version, 2);
do_check_eq(update.targetApplications[0].minVersion, 1);
do_check_eq(update.targetApplications[0].maxVersion, 2);
run_test_2();
}
/* /*
* Tests that the security checks are applied correctly * Tests that the security checks are applied correctly
@ -68,169 +73,240 @@ var updateKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD/H3XtsjvaB5+PJqbh
"NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf" + "NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf" +
"awB/zH4KaPiY3vnrzQIDAQAB"; "awB/zH4KaPiY3vnrzQIDAQAB";
add_task(function* () { function run_test_2() {
for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) { AddonUpdateChecker.checkForUpdates("test_bug378216_5@tests.mozilla.org",
try { updateKey,
yield checkUpdates("test_bug378216_5@tests.mozilla.org", "http://localhost:4444/data/test_updatecheck.rdf", {
updateKey, file); onUpdateCheckComplete: function(updates) {
throw "Expected the update check to fail"; do_throw("Expected the update check to fail");
} catch (e) {} },
}
});
add_task(function* () { onUpdateCheckError: function(status) {
for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) { run_test_3();
try {
yield checkUpdates("test_bug378216_7@tests.mozilla.org",
updateKey, file);
throw "Expected the update check to fail";
} catch (e) {}
}
});
add_task(function* () {
// Make sure that the JSON manifest is rejected when an update key is
// required, but perform the remaining tests which aren't expected to fail
// because of the update key, without requiring one for the JSON variant.
try {
let updates = yield checkUpdates("test_bug378216_8@tests.mozilla.org",
updateKey, "test_updatecheck.json");
throw "Expected the update check to fail";
} catch(e) {}
for (let [file, key] of [["test_updatecheck.rdf", updateKey],
["test_updatecheck.json", null]]) {
let updates = yield checkUpdates("test_bug378216_8@tests.mozilla.org",
key, file);
equal(updates.length, 1);
ok(!("updateURL" in updates[0]));
}
});
add_task(function* () {
for (let [file, key] of [["test_updatecheck.rdf", updateKey],
["test_updatecheck.json", null]]) {
let updates = yield checkUpdates("test_bug378216_9@tests.mozilla.org",
key, file);
equal(updates.length, 1);
equal(updates[0].version, "2.0");
ok("updateURL" in updates[0]);
}
});
add_task(function* () {
for (let [file, key] of [["test_updatecheck.rdf", updateKey],
["test_updatecheck.json", null]]) {
let updates = yield checkUpdates("test_bug378216_10@tests.mozilla.org",
key, file);
equal(updates.length, 1);
equal(updates[0].version, "2.0");
ok("updateURL" in updates[0]);
}
});
add_task(function* () {
for (let [file, key] of [["test_updatecheck.rdf", updateKey],
["test_updatecheck.json", null]]) {
let updates = yield checkUpdates("test_bug378216_11@tests.mozilla.org",
key, file);
equal(updates.length, 1);
equal(updates[0].version, "2.0");
ok("updateURL" in updates[0]);
}
});
add_task(function* () {
for (let [file, key] of [["test_updatecheck.rdf", updateKey],
["test_updatecheck.json", null]]) {
let updates = yield checkUpdates("test_bug378216_12@tests.mozilla.org",
key, file);
equal(updates.length, 1);
do_check_false("updateURL" in updates[0]);
}
});
add_task(function* () {
for (let [file, key] of [["test_updatecheck.rdf", updateKey],
["test_updatecheck.json", null]]) {
let updates = yield checkUpdates("test_bug378216_13@tests.mozilla.org",
key, file);
equal(updates.length, 1);
equal(updates[0].version, "2.0");
ok("updateURL" in updates[0]);
}
});
add_task(function* () {
for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) {
let updates = yield checkUpdates("test_bug378216_14@tests.mozilla.org",
null, file);
equal(updates.length, 0);
}
});
add_task(function* () {
for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) {
try {
yield checkUpdates("test_bug378216_15@tests.mozilla.org",
null, file);
throw "Update check should have failed";
} catch (e) {
equal(e.status, AddonUpdateChecker.ERROR_PARSE_ERROR);
} }
} });
}); }
add_task(function* () { function run_test_3() {
for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) { AddonUpdateChecker.checkForUpdates("test_bug378216_7@tests.mozilla.org",
let updates = yield checkUpdates("ignore-compat@tests.mozilla.org", updateKey,
null, file); "http://localhost:4444/data/test_updatecheck.rdf", {
equal(updates.length, 3); onUpdateCheckComplete: function(updates) {
let update = AddonUpdateChecker.getNewestCompatibleUpdate( do_throw("Expected the update check to fail");
updates, null, null, true); },
notEqual(update, null);
equal(update.version, 2);
}
});
add_task(function* () { onUpdateCheckError: function(status) {
for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) { run_test_4();
let updates = yield checkUpdates("compat-override@tests.mozilla.org", }
null, file); });
equal(updates.length, 3); }
let overrides = [{
type: "incompatible",
minVersion: 1,
maxVersion: 2,
appID: "xpcshell@tests.mozilla.org",
appMinVersion: 0.1,
appMaxVersion: 0.2
}, {
type: "incompatible",
minVersion: 2,
maxVersion: 2,
appID: "xpcshell@tests.mozilla.org",
appMinVersion: 1,
appMaxVersion: 2
}];
let update = AddonUpdateChecker.getNewestCompatibleUpdate(
updates, null, null, true, false, overrides);
notEqual(update, null);
equal(update.version, 1);
}
});
add_task(function* () { function run_test_4() {
for (let file of ["test_updatecheck.rdf", "test_updatecheck.json"]) { AddonUpdateChecker.checkForUpdates("test_bug378216_8@tests.mozilla.org",
let updates = yield checkUpdates("compat-strict-optin@tests.mozilla.org", updateKey,
null, file); "http://localhost:4444/data/test_updatecheck.rdf", {
equal(updates.length, 1); onUpdateCheckComplete: function(updates) {
let update = AddonUpdateChecker.getNewestCompatibleUpdate( do_check_eq(updates.length, 1);
updates, null, null, true, false); do_check_false("updateURL" in updates[0]);
equal(update, null); run_test_5();
} },
});
onUpdateCheckError: function(status) {
do_throw("Update check failed with status " + status);
}
});
}
function run_test_5() {
AddonUpdateChecker.checkForUpdates("test_bug378216_9@tests.mozilla.org",
updateKey,
"http://localhost:4444/data/test_updatecheck.rdf", {
onUpdateCheckComplete: function(updates) {
do_check_eq(updates.length, 1);
do_check_eq(updates[0].version, "2.0");
do_check_true("updateURL" in updates[0]);
run_test_6();
},
onUpdateCheckError: function(status) {
do_throw("Update check failed with status " + status);
}
});
}
function run_test_6() {
AddonUpdateChecker.checkForUpdates("test_bug378216_10@tests.mozilla.org",
updateKey,
"http://localhost:4444/data/test_updatecheck.rdf", {
onUpdateCheckComplete: function(updates) {
do_check_eq(updates.length, 1);
do_check_eq(updates[0].version, "2.0");
do_check_true("updateURL" in updates[0]);
run_test_7();
},
onUpdateCheckError: function(status) {
do_throw("Update check failed with status " + status);
}
});
}
function run_test_7() {
AddonUpdateChecker.checkForUpdates("test_bug378216_11@tests.mozilla.org",
updateKey,
"http://localhost:4444/data/test_updatecheck.rdf", {
onUpdateCheckComplete: function(updates) {
do_check_eq(updates.length, 1);
do_check_eq(updates[0].version, "2.0");
do_check_true("updateURL" in updates[0]);
run_test_8();
},
onUpdateCheckError: function(status) {
do_throw("Update check failed with status " + status);
}
});
}
function run_test_8() {
AddonUpdateChecker.checkForUpdates("test_bug378216_12@tests.mozilla.org",
updateKey,
"http://localhost:4444/data/test_updatecheck.rdf", {
onUpdateCheckComplete: function(updates) {
do_check_eq(updates.length, 1);
do_check_false("updateURL" in updates[0]);
run_test_9();
},
onUpdateCheckError: function(status) {
do_throw("Update check failed with status " + status);
}
});
}
function run_test_9() {
AddonUpdateChecker.checkForUpdates("test_bug378216_13@tests.mozilla.org",
updateKey,
"http://localhost:4444/data/test_updatecheck.rdf", {
onUpdateCheckComplete: function(updates) {
do_check_eq(updates.length, 1);
do_check_eq(updates[0].version, "2.0");
do_check_true("updateURL" in updates[0]);
run_test_10();
},
onUpdateCheckError: function(status) {
do_throw("Update check failed with status " + status);
}
});
}
function run_test_10() {
AddonUpdateChecker.checkForUpdates("test_bug378216_14@tests.mozilla.org",
null,
"http://localhost:4444/data/test_updatecheck.rdf", {
onUpdateCheckComplete: function(updates) {
do_check_eq(updates.length, 0);
run_test_11();
},
onUpdateCheckError: function(status) {
do_throw("Update check failed with status " + status);
}
});
}
function run_test_11() {
AddonUpdateChecker.checkForUpdates("test_bug378216_15@tests.mozilla.org",
null,
"http://localhost:4444/data/test_updatecheck.rdf", {
onUpdateCheckComplete: function(updates) {
do_throw("Update check should have failed");
},
onUpdateCheckError: function(status) {
do_check_eq(status, AddonUpdateChecker.ERROR_PARSE_ERROR);
run_test_12();
}
});
}
function run_test_12() {
AddonUpdateChecker.checkForUpdates("ignore-compat@tests.mozilla.org",
null,
"http://localhost:4444/data/test_updatecheck.rdf", {
onUpdateCheckComplete: function(updates) {
do_check_eq(updates.length, 3);
let update = AddonUpdateChecker.getNewestCompatibleUpdate(updates,
null,
null,
true);
do_check_neq(update, null);
do_check_eq(update.version, 2);
run_test_13();
},
onUpdateCheckError: function(status) {
do_throw("Update check failed with status " + status);
}
});
}
function run_test_13() {
AddonUpdateChecker.checkForUpdates("compat-override@tests.mozilla.org",
null,
"http://localhost:4444/data/test_updatecheck.rdf", {
onUpdateCheckComplete: function(updates) {
do_check_eq(updates.length, 3);
let overrides = [{
type: "incompatible",
minVersion: 1,
maxVersion: 2,
appID: "xpcshell@tests.mozilla.org",
appMinVersion: 0.1,
appMaxVersion: 0.2
}, {
type: "incompatible",
minVersion: 2,
maxVersion: 2,
appID: "xpcshell@tests.mozilla.org",
appMinVersion: 1,
appMaxVersion: 2
}];
let update = AddonUpdateChecker.getNewestCompatibleUpdate(updates,
null,
null,
true,
false,
overrides);
do_check_neq(update, null);
do_check_eq(update.version, 1);
run_test_14();
},
onUpdateCheckError: function(status) {
do_throw("Update check failed with status " + status);
}
});
}
function run_test_14() {
AddonUpdateChecker.checkForUpdates("compat-strict-optin@tests.mozilla.org",
null,
"http://localhost:4444/data/test_updatecheck.rdf", {
onUpdateCheckComplete: function(updates) {
do_check_eq(updates.length, 1);
let update = AddonUpdateChecker.getNewestCompatibleUpdate(updates,
null,
null,
true,
false);
do_check_eq(update, null);
end_test();
},
onUpdateCheckError: function(status) {
do_throw("Update check failed with status " + status);
}
});
}

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

@ -279,7 +279,6 @@ skip-if = os == "android"
# Bug 676992: test consistently hangs on Android # Bug 676992: test consistently hangs on Android
skip-if = os == "android" skip-if = os == "android"
run-sequentially = Uses hardcoded ports in xpi files. run-sequentially = Uses hardcoded ports in xpi files.
[test_json_updatecheck.js]
[test_updateid.js] [test_updateid.js]
# Bug 676992: test consistently hangs on Android # Bug 676992: test consistently hangs on Android
skip-if = os == "android" skip-if = os == "android"