Skip to content

Commit

Permalink
Bug 1042881 - ManifestHelper() must resolve uris against the manifest…
Browse files Browse the repository at this point in the history
… url r=myk
  • Loading branch information
Fabrice Desré committed Jul 30, 2014
1 parent 7756f0c commit be9dd03
Show file tree
Hide file tree
Showing 17 changed files with 157 additions and 62 deletions.
3 changes: 2 additions & 1 deletion b2g/chrome/content/shell.js
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,8 @@ var WebappsHelper = {
if (!aManifest)
return;

let manifest = new ManifestHelper(aManifest, json.origin);
let manifest = new ManifestHelper(aManifest, json.origin,
json.manifestURL);
let payload = {
timestamp: json.timestamp,
url: manifest.fullLaunchPath(json.startPoint),
Expand Down
9 changes: 5 additions & 4 deletions b2g/components/AlertsHelper.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ let AlertsHelper = {
this._listeners[uid] = listener;

appsService.getManifestFor(listener.manifestURL).then((manifest) => {
let helper = new ManifestHelper(manifest, listener.manifestURL);
let app = appsService.getAppByManifestURL(listener.manifestURL);
let helper = new ManifestHelper(manifest, app.origin, app.manifestURL);
let getNotificationURLFor = function(messages) {
if (!messages) {
return null;
Expand All @@ -179,8 +180,7 @@ let AlertsHelper = {
return helper.fullLaunchPath();
} else if (typeof message === "object" &&
kNotificationSystemMessageName in message) {
return helper.resolveFromOrigin(
message[kNotificationSystemMessageName]);
return helper.resolveURL(message[kNotificationSystemMessageName]);
}
}

Expand Down Expand Up @@ -220,7 +220,8 @@ let AlertsHelper = {
// If we have a manifest URL, get the icon and title from the manifest
// to prevent spoofing.
appsService.getManifestFor(manifestURL).then((manifest) => {
let helper = new ManifestHelper(manifest, manifestURL);
let app = appsService.getAppByManifestURL(manifestURL);
let helper = new ManifestHelper(manifest, app.origin, manifestURL);
send(helper.name, helper.iconURLForSize(kNotificationIconSize));
});
},
Expand Down
7 changes: 5 additions & 2 deletions browser/modules/WebappManager.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ this.WebappManager = {
}
} else if (aMessage.name == "Webapps:Install:Return:OK" &&
!data.isPackage) {
let manifest = new ManifestHelper(data.app.manifest, data.app.origin);
let manifest = new ManifestHelper(data.app.manifest,
data.app.origin,
data.app.manifestURL);
if (!manifest.appcache_path) {
this.installations[manifestURL].resolve();
}
Expand Down Expand Up @@ -172,7 +174,8 @@ this.WebappManager = {
};

let requestingURI = chromeWin.makeURI(aData.from);
let manifest = new ManifestHelper(jsonManifest, aData.app.origin);
let app = aData.app;
let manifest = new ManifestHelper(jsonManifest, app.origin, app.manifestURL);

let host;
try {
Expand Down
5 changes: 4 additions & 1 deletion dom/activities/src/ActivitiesService.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,10 @@ let Activities = {
let results = [];
aManifests.forEach((aManifest, i) => {
let manifestURL = aResults.options[i].manifest;
let helper = new ManifestHelper(aManifest.manifest, manifestURL);
// Not passing the origin is fine here since we only need
// helper.name which doesn't rely on url resolution.
let helper =
new ManifestHelper(aManifest.manifest, manifestURL, manifestURL);
results.push({
manifestURL: manifestURL,
iconURL: aResults.options[i].icon,
Expand Down
46 changes: 31 additions & 15 deletions dom/apps/src/AppsUtils.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",

// Shared code for AppsServiceChild.jsm, Webapps.jsm and Webapps.js

this.EXPORTED_SYMBOLS = ["AppsUtils", "ManifestHelper", "isAbsoluteURI", "mozIApplication"];
this.EXPORTED_SYMBOLS =
["AppsUtils", "ManifestHelper", "isAbsoluteURI", "mozIApplication"];

function debug(s) {
//dump("-*- AppsUtils.jsm: " + s + "\n");
Expand Down Expand Up @@ -373,7 +374,8 @@ this.AppsUtils = {

// Nor through localized names
if ('locales' in aNewManifest) {
let defaultName = new ManifestHelper(aOldManifest, aApp.origin).name;
let defaultName =
new ManifestHelper(aOldManifest, aApp.origin, aApp.manifestURL).name;
for (let locale in aNewManifest.locales) {
let entry = aNewManifest.locales[locale];
if (!entry.name) {
Expand Down Expand Up @@ -593,11 +595,25 @@ this.AppsUtils = {
/**
* Helper object to access manifest information with locale support
*/
this.ManifestHelper = function(aManifest, aOrigin) {
this._origin = Services.io.newURI(aOrigin, null, null);
this.ManifestHelper = function(aManifest, aOrigin, aManifestURL) {
// If the app is packaged, we resolve uris against the origin.
// If it's not, against the manifest url.

if (!aOrigin || !aManifestURL) {
throw Error("ManifestHelper needs both origin and manifestURL");
}

this._baseURI = Services.io.newURI(
aOrigin.startsWith("app://") ? aOrigin : aManifestURL, null, null);

// We keep the manifest url in all cases since we need it to
// resolve the package path for packaged apps.
this._manifestURL = Services.io.newURI(aManifestURL, null, null);

this._manifest = aManifest;
let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry)
.QueryInterface(Ci.nsIToolkitChromeRegistry);
let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"]
.getService(Ci.nsIXULChromeRegistry)
.QueryInterface(Ci.nsIToolkitChromeRegistry);
let locale = chrome.getSelectedLocale("global").toLowerCase();
this._localeRoot = this._manifest;

Expand Down Expand Up @@ -686,7 +702,7 @@ ManifestHelper.prototype = {
iconSizes.sort((a, b) => a - b);
let biggestIconSize = iconSizes.pop();
let biggestIcon = icons[biggestIconSize];
let biggestIconURL = this._origin.resolve(biggestIcon);
let biggestIconURL = this._baseURI.resolve(biggestIcon);

return biggestIconURL;
},
Expand All @@ -700,7 +716,7 @@ ManifestHelper.prototype = {
for (let size in icons) {
let iSize = parseInt(size);
if (Math.abs(iSize - aSize) < dist) {
icon = this._origin.resolve(icons[size]);
icon = this._baseURI.resolve(icons[size]);
dist = Math.abs(iSize - aSize);
}
}
Expand All @@ -711,7 +727,7 @@ ManifestHelper.prototype = {
// If no start point is specified, we use the root launch path.
// In all error cases, we just return null.
if ((aStartPoint || "") === "") {
return this._origin.resolve(this._localeProp("launch_path") || "");
return this._baseURI.resolve(this._localeProp("launch_path") || "/");
}

// Search for the l10n entry_points property.
Expand All @@ -721,28 +737,28 @@ ManifestHelper.prototype = {
}

if (entryPoints[aStartPoint]) {
return this._origin.resolve(entryPoints[aStartPoint].launch_path || "");
return this._baseURI.resolve(entryPoints[aStartPoint].launch_path || "/");
}

return null;
},

resolveFromOrigin: function(aURI) {
resolveURL: function(aURI) {
// This should be enforced higher up, but check it here just in case.
if (isAbsoluteURI(aURI)) {
throw new Error("Webapps.jsm: non-relative URI passed to resolveFromOrigin");
throw new Error("Webapps.jsm: non-relative URI passed to resolve");
}
return this._origin.resolve(aURI);
return this._baseURI.resolve(aURI);
},

fullAppcachePath: function() {
let appcachePath = this._localeProp("appcache_path");
return this._origin.resolve(appcachePath ? appcachePath : "");
return this._baseURI.resolve(appcachePath ? appcachePath : "/");
},

fullPackagePath: function() {
let packagePath = this._localeProp("package_path");
return this._origin.resolve(packagePath ? packagePath : "");
return this._manifestURL.resolve(packagePath ? packagePath : "/");
},

get role() {
Expand Down
3 changes: 2 additions & 1 deletion dom/apps/src/PermissionsInstaller.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ this.PermissionsInstaller = {
installPermissions: function installPermissions(aApp, aIsReinstall, aOnError,
aIsSystemUpdate) {
try {
let newManifest = new ManifestHelper(aApp.manifest, aApp.origin);
let newManifest =
new ManifestHelper(aApp.manifest, aApp.origin, aApp.manifestURL);
if (!newManifest.permissions && !aIsReinstall) {
return;
}
Expand Down
46 changes: 27 additions & 19 deletions dom/apps/src/Webapps.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,8 @@ this.DOMApplicationRegistry = {
updateOfflineCacheForApp: function(aId) {
let app = this.webapps[aId];
this._readManifests([{ id: aId }]).then((aResult) => {
let manifest = new ManifestHelper(aResult[0].manifest, app.origin);
let manifest =
new ManifestHelper(aResult[0].manifest, app.origin, app.manifestURL);
OfflineCacheInstaller.installCache({
cachePath: app.cachePath,
appId: aId,
Expand Down Expand Up @@ -675,7 +676,7 @@ this.DOMApplicationRegistry = {
return;
}

let manifest = new ManifestHelper(aManifest, aApp.origin);
let manifest = new ManifestHelper(aManifest, aApp.origin, aApp.manifestURL);
let launchPathURI = Services.io.newURI(manifest.fullLaunchPath(aEntryPoint), null, null);
let manifestURI = Services.io.newURI(aApp.manifestURL, null, null);
root.messages.forEach(function registerPages(aMessage) {
Expand All @@ -689,7 +690,7 @@ this.DOMApplicationRegistry = {
let fullHandlerPath;
try {
if (handlerPath && handlerPath.trim()) {
fullHandlerPath = manifest.resolveFromOrigin(handlerPath);
fullHandlerPath = manifest.resolveURL(handlerPath);
} else {
throw new Error("Empty or blank handler path.");
}
Expand All @@ -705,7 +706,7 @@ this.DOMApplicationRegistry = {

if (SystemMessagePermissionsChecker
.isSystemMessagePermittedToRegister(messageName,
aApp.origin,
aApp.manifestURL,
aManifest)) {
msgmgr.registerPage(messageName, handlerPageURI, manifestURI);
}
Expand Down Expand Up @@ -733,7 +734,7 @@ this.DOMApplicationRegistry = {
return;
}

let manifest = new ManifestHelper(aManifest, aApp.origin);
let manifest = new ManifestHelper(aManifest, aApp.origin, aApp.manifestURL);
let launchPathURI = Services.io.newURI(manifest.fullLaunchPath(aEntryPoint),
null, null);
let manifestURI = Services.io.newURI(aApp.manifestURL, null, null);
Expand All @@ -747,7 +748,7 @@ this.DOMApplicationRegistry = {
let handlerPath = connection.handler_path;
if (handlerPath) {
try {
fullHandlerPath = manifest.resolveFromOrigin(handlerPath);
fullHandlerPath = manifest.resolveURL(handlerPath);
} catch(e) {
debug("Connection's handler path is invalid. Skipping: keyword: " +
keyword + " handler_path: " + handlerPath);
Expand All @@ -760,7 +761,7 @@ this.DOMApplicationRegistry = {

if (SystemMessagePermissionsChecker
.isSystemMessagePermittedToRegister("connection",
aApp.origin,
aApp.manifestURL,
aManifest)) {
msgmgr.registerPage("connection", handlerPageURI, manifestURI);
}
Expand Down Expand Up @@ -812,7 +813,7 @@ this.DOMApplicationRegistry = {
return activitiesToRegister;
}

let manifest = new ManifestHelper(aManifest, aApp.origin);
let manifest = new ManifestHelper(aManifest, aApp.origin, aApp.manifestURL);
for (let activity in root.activities) {
let description = root.activities[activity];
let href = description.href;
Expand All @@ -821,7 +822,7 @@ this.DOMApplicationRegistry = {
}

try {
href = manifest.resolveFromOrigin(href);
href = manifest.resolveURL(href);
} catch (e) {
debug("Activity href (" + href + ") is invalid, skipping. " +
"Error is: " + e);
Expand Down Expand Up @@ -851,7 +852,7 @@ this.DOMApplicationRegistry = {

if (SystemMessagePermissionsChecker
.isSystemMessagePermittedToRegister("activity",
aApp.origin,
aApp.manifestURL,
aManifest)) {
msgmgr.registerPage("activity", launchPathURI, manifestURI);
}
Expand Down Expand Up @@ -961,7 +962,8 @@ this.DOMApplicationRegistry = {
return;
}

let localeManifest = new ManifestHelper(manifest, app.origin);
let localeManifest =
new ManifestHelper(manifest, app.origin, app.manifestURL);

app.name = manifest.name;
app.csp = manifest.csp || "";
Expand Down Expand Up @@ -1463,7 +1465,8 @@ this.DOMApplicationRegistry = {
let results = yield this._readManifests([{ id: id }]);

let jsonManifest = results[0].manifest;
let manifest = new ManifestHelper(jsonManifest, app.origin);
let manifest =
new ManifestHelper(jsonManifest, app.origin, app.manifestURL);

if (manifest.appcache_path) {
debug("appcache found");
Expand Down Expand Up @@ -1497,7 +1500,7 @@ this.DOMApplicationRegistry = {
throw new Error("MISSING_UPDATE_MANIFEST");
}

let manifest = new ManifestHelper(json, app.manifestURL);
let manifest = new ManifestHelper(json, app.origin, app.manifestURL);
let newApp = {
manifestURL: aManifestURL,
origin: app.origin,
Expand Down Expand Up @@ -1808,7 +1811,8 @@ this.DOMApplicationRegistry = {
}
}
};
let helper = new ManifestHelper(manifest, aData.manifestURL);
let helper =
new ManifestHelper(manifest, aData.origin, aData.manifestURL);
debug("onlyCheckAppCache - launch updateSvc.checkForUpdate for " +
helper.fullAppcachePath());
updateSvc.checkForUpdate(Services.io.newURI(helper.fullAppcachePath(), null, null),
Expand Down Expand Up @@ -1990,7 +1994,8 @@ this.DOMApplicationRegistry = {
let manFile = OS.Path.join(dir, "staged-update.webapp");
yield this._writeFile(manFile, JSON.stringify(aNewManifest));

let manifest = new ManifestHelper(aNewManifest, aApp.manifestURL);
let manifest =
new ManifestHelper(aNewManifest, aApp.origin, aApp.manifestURL);
// A package is available: set downloadAvailable to fire the matching
// event.
aApp.downloadAvailable = true;
Expand Down Expand Up @@ -2036,7 +2041,8 @@ this.DOMApplicationRegistry = {
let manFile = OS.Path.join(dir, "manifest.webapp");
yield this._writeFile(manFile, JSON.stringify(aNewManifest));

manifest = new ManifestHelper(aNewManifest, aApp.origin);
manifest =
new ManifestHelper(aNewManifest, aApp.origin, aApp.manifestURL);

if (supportUseCurrentProfile()) {
// Update the permissions for this app.
Expand All @@ -2055,7 +2061,8 @@ this.DOMApplicationRegistry = {
aApp.role = manifest.role || "";
aApp.updateTime = Date.now();
} else {
manifest = new ManifestHelper(aOldManifest, aApp.origin);
manifest =
new ManifestHelper(aOldManifest, aApp.origin, aApp.manifestURL);
}

// Update the registry.
Expand Down Expand Up @@ -2564,7 +2571,8 @@ this.DOMApplicationRegistry = {
yield this._writeManifestFile(id, aData.isPackage, jsonManifest);

debug("app.origin: " + app.origin);
let manifest = new ManifestHelper(jsonManifest, app.origin);
let manifest =
new ManifestHelper(jsonManifest, app.origin, app.manifestURL);

let appObject = this._cloneApp(aData, app, manifest, jsonManifest, id, localId);

Expand Down Expand Up @@ -2618,7 +2626,7 @@ this.DOMApplicationRegistry = {

// origin for install apps is meaningless here, since it's app:// and this
// can't be used to resolve package paths.
manifest = new ManifestHelper(jsonManifest, app.manifestURL);
manifest = new ManifestHelper(jsonManifest, app.origin, app.manifestURL);

this.queuedPackageDownload[app.manifestURL] = {
manifest: manifest,
Expand Down
1 change: 1 addition & 0 deletions dom/apps/tests/chrome.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ support-files =
[test_apps_service.xul]
[test_bug_945152.html]
run-if = os == 'linux'
[test_manifest_helper.xul]
[test_operator_app_install.js]
[test_operator_app_install.xul]
# bug 928262
Expand Down
Loading

0 comments on commit be9dd03

Please sign in to comment.