mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1191619 - Support extensions with no packaged manifest.webapp r=ferjm
This commit is contained in:
parent
6c5bfd7cca
commit
7500f65897
@ -14,6 +14,8 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Extension.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ValueExtractor",
|
||||
"resource://gre/modules/ValueExtractor.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "console",
|
||||
"@mozilla.org/consoleservice;1",
|
||||
@ -64,6 +66,79 @@ this.UserCustomizations = {
|
||||
}
|
||||
},
|
||||
|
||||
// Checks that this is a valid extension manifest.
|
||||
// The format is documented at https://developer.chrome.com/extensions/manifest
|
||||
checkExtensionManifest: function(aManifest) {
|
||||
if (!aManifest) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const extractor = new ValueExtractor(console);
|
||||
const manifestVersionSpec = {
|
||||
objectName: "extension manifest",
|
||||
object: aManifest,
|
||||
property: "manifest_version",
|
||||
expectedType: "number",
|
||||
trim: true
|
||||
}
|
||||
|
||||
const nameSpec = {
|
||||
objectName: "extension manifest",
|
||||
object: aManifest,
|
||||
property: "name",
|
||||
expectedType: "string",
|
||||
trim: true
|
||||
}
|
||||
|
||||
const versionSpec = {
|
||||
objectName: "extension manifest",
|
||||
object: aManifest,
|
||||
property: "version",
|
||||
expectedType: "string",
|
||||
trim: true
|
||||
}
|
||||
|
||||
let res =
|
||||
extractor.extractValue(manifestVersionSpec) !== undefined &&
|
||||
extractor.extractValue(nameSpec) !== undefined &&
|
||||
extractor.extractValue(versionSpec) !== undefined;
|
||||
|
||||
return res;
|
||||
},
|
||||
|
||||
// Converts a chrome extension manifest into a webapp manifest.
|
||||
convertManifest: function(aManifest) {
|
||||
if (!aManifest) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Set the type to privileged to ensure we only allow signed addons.
|
||||
let result = {
|
||||
"type": "privileged",
|
||||
"name": aManifest.name,
|
||||
"role": "addon"
|
||||
}
|
||||
|
||||
if (aManifest.description) {
|
||||
result.description = aManifest.description;
|
||||
}
|
||||
|
||||
if (aManifest.icons) {
|
||||
result.icons = aManifest.icons;
|
||||
}
|
||||
|
||||
// chrome extension manifests have a single 'author' property, that we
|
||||
// map to 'developer.name'.
|
||||
// Note that it has to match the one in the mini-manifest.
|
||||
if (aManifest.author) {
|
||||
result.developer = {
|
||||
name: aManifest.author
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
init: function() {
|
||||
this._enabled = false;
|
||||
try {
|
||||
|
@ -3757,11 +3757,21 @@ this.DOMApplicationRegistry = {
|
||||
aIsSigned) {
|
||||
this._checkSignature(aNewApp, aIsSigned, aIsLocalFileInstall);
|
||||
|
||||
if (!aZipReader.hasEntry("manifest.webapp")) {
|
||||
// Chrome-style extensions only have a manifest.json manifest.
|
||||
// In this case we extract it, and convert it to a minimal
|
||||
// manifest.webapp manifest.
|
||||
// Packages that contain both manifest.webapp and manifest.json
|
||||
// are considered as apps, not extensions.
|
||||
let hasWebappManifest = aZipReader.hasEntry("manifest.webapp");
|
||||
let hasJsonManifest = aZipReader.hasEntry("manifest.json");
|
||||
|
||||
if (!hasWebappManifest && !hasJsonManifest) {
|
||||
throw "MISSING_MANIFEST";
|
||||
}
|
||||
|
||||
let istream = aZipReader.getInputStream("manifest.webapp");
|
||||
let istream =
|
||||
aZipReader.getInputStream(hasWebappManifest ? "manifest.webapp"
|
||||
: "manifest.json");
|
||||
|
||||
// Obtain a converter to read from a UTF-8 encoded input stream.
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
@ -3771,6 +3781,14 @@ this.DOMApplicationRegistry = {
|
||||
let newManifest = JSON.parse(converter.ConvertToUnicode(
|
||||
NetUtil.readInputStreamToString(istream, istream.available()) || ""));
|
||||
|
||||
if (!hasWebappManifest) {
|
||||
// Validate the extension manifest, and convert it.
|
||||
if (!UserCustomizations.checkExtensionManifest(newManifest)) {
|
||||
throw "INVALID_MANIFEST";
|
||||
}
|
||||
newManifest = UserCustomizations.convertManifest(newManifest);
|
||||
}
|
||||
|
||||
if (!AppsUtils.checkManifest(newManifest, aOldApp)) {
|
||||
throw "INVALID_MANIFEST";
|
||||
}
|
||||
@ -3814,8 +3832,11 @@ this.DOMApplicationRegistry = {
|
||||
let isLangPack = newManifest.role === "langpack" &&
|
||||
(aIsSigned || allowUnsignedLangpack);
|
||||
|
||||
let isAddon = newManifest.role === "addon" &&
|
||||
(aIsSigned || AppsUtils.allowUnsignedAddons);
|
||||
|
||||
let status = AppsUtils.getAppManifestStatus(newManifest);
|
||||
if (status > maxStatus && !isLangPack) {
|
||||
if (status > maxStatus && !isLangPack && !isAddon) {
|
||||
throw "INVALID_SECURITY_LEVEL";
|
||||
}
|
||||
|
||||
|
Binary file not shown.
6
dom/apps/tests/addons/invalid.webapp
Normal file
6
dom/apps/tests/addons/invalid.webapp
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "Addon app with an invalid name",
|
||||
"description": "Let me inject script and css!",
|
||||
"developer": { "name": "The Mozilla Community" },
|
||||
"package_path" : "application.zip"
|
||||
}
|
1
dom/apps/tests/addons/invalid.webapp^headers^
Normal file
1
dom/apps/tests/addons/invalid.webapp^headers^
Normal file
@ -0,0 +1 @@
|
||||
Content-Type: application/manifest+json
|
@ -4,6 +4,7 @@
|
||||
"manifest_version": 2,
|
||||
"permissions": ["tabs"],
|
||||
"description": "Let me inject script and css!",
|
||||
"author": "The Mozilla Community",
|
||||
"content_scripts": [
|
||||
{"matches": ["http://mochi.test/tests/dom/apps/tests/addons/index.html"],
|
||||
"js": ["script.js", "script2.js", "invalid.js", "script.js"],
|
||||
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"name": "Addon app",
|
||||
"description": "Let me inject script and css!",
|
||||
"role": "addon"
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "Addon app",
|
||||
"description": "Let me inject script and css!",
|
||||
"developer": { "name": "The Mozilla Community" },
|
||||
"package_path" : "application.zip"
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
skip-if = e10s
|
||||
support-files =
|
||||
addons/application.zip
|
||||
addons/invalid.webapp
|
||||
addons/invalid.webapp^headers^
|
||||
addons/update.webapp
|
||||
addons/update.webapp^headers^
|
||||
addons/index.html
|
||||
|
@ -20,7 +20,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1042881
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
let appManifestURL = "http://mochi.test:8888/tests/dom/apps/tests/addons/update.webapp";
|
||||
const baseURL = "http://mochi.test:8888/tests/dom/apps/tests/addons/";
|
||||
|
||||
const appManifestURL = baseURL + "update.webapp";
|
||||
const invalidAppManifestURL = baseURL + "invalid.webapp";
|
||||
|
||||
let gGenerator = runTest();
|
||||
|
||||
@ -68,7 +71,7 @@ function openPage(pageURL, messages) {
|
||||
|
||||
let apps = [];
|
||||
|
||||
function installApp(manifestURL) {
|
||||
function installApp(manifestURL, expectedError) {
|
||||
info("About to install app at " + manifestURL);
|
||||
let req = navigator.mozApps.installPackage(manifestURL);
|
||||
req.onsuccess = function() {
|
||||
@ -82,6 +85,15 @@ function installApp(manifestURL) {
|
||||
is(req.result.installState, "installed", "app downloaded");
|
||||
continueTest();
|
||||
}
|
||||
|
||||
req.result.ondownloaderror = function() {
|
||||
if (expectedError) {
|
||||
ok(true, "expected installation error.");
|
||||
} else {
|
||||
ok(false, "unexpected installation error.");
|
||||
}
|
||||
continueTest();
|
||||
}
|
||||
}
|
||||
}
|
||||
req.onerror = mozAppsError;
|
||||
@ -116,8 +128,12 @@ function runTest() {
|
||||
"Uncustomized content", "rgb(0, 0, 0)"]);
|
||||
yield undefined;
|
||||
|
||||
// Install addon app.
|
||||
installApp(appManifestURL);
|
||||
// Install addon app with an invalid manifest.
|
||||
installApp(invalidAppManifestURL, true);
|
||||
yield undefined;
|
||||
|
||||
// Install valid addon app.
|
||||
installApp(appManifestURL, false);
|
||||
yield undefined;
|
||||
|
||||
// Opens the iframe to the test page, customized.
|
||||
|
Loading…
Reference in New Issue
Block a user