Bug 306478 - Extension manager should use xpinstall crypto hashes. r=bsmedberg

This commit is contained in:
rob_strong%exchangecode.com 2005-09-28 04:33:38 +00:00
Родитель 39d6430f14
Коммит 89156751b9
5 изменённых файлов: 48 добавлений и 233 удалений

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

@ -319,10 +319,9 @@ XPInstallDownloadManager.prototype = {
}
var type = isExtensions ? nsIUpdateItem.TYPE_EXTENSION : nsIUpdateItem.TYPE_THEME;
// gExtensionManager.addDownload(displayName, url, iconURL, type);
var item = Components.classes["@mozilla.org/updates/item;1"]
.createInstance(Components.interfaces.nsIUpdateItem);
item.init(url, " ", "app-profile", "", "", displayName, url, iconURL, "", type);
item.init(url, " ", "app-profile", "", "", displayName, url, "", iconURL, "", type);
items.push(item);
// Advance the enumerator

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

@ -326,6 +326,7 @@ var gFoundPage = {
checkbox.setAttribute("type", "update");
checkbox.label = item.name + " " + item.version;
checkbox.setAttribute("URL", item.xpiURL);
checkbox.setAttribute("hash", item.xpiHash);
checkbox.infoURL = "";
checkbox.internalName = "";
uri.spec = item.xpiURL;
@ -407,6 +408,7 @@ var gInstallingPage = {
// Get XPInstallManager and kick off download/install
// process, registering us as an observer.
var items = [];
var hashes = [];
this._objs = [];
this._restartRequired = false;
@ -418,13 +420,14 @@ var gInstallingPage = {
for (var i = 0; i < checkboxes.length; ++i) {
if (checkboxes[i].type == "update" && checkboxes[i].checked) {
items.push(checkboxes[i].URL);
hashes.push(checkboxes[i].hash);
this._objs.push({ name: checkboxes[i].label });
}
}
var xpimgr = Components.classes["@mozilla.org/xpinstall/install-manager;1"]
.createInstance(Components.interfaces.nsIXPInstallManager);
xpimgr.initManagerFromChrome(items, items.length, this);
xpimgr.initManagerWithHashes(items, hashes, items.length, this);
},
/////////////////////////////////////////////////////////////////////////////

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

@ -1,217 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE bindings SYSTEM "chrome://mozapps/locale/extensions/update.dtd">
<bindings id="updatesBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="updateCategorySet" extends="chrome://global/content/bindings/radio.xml#radiogroup">
<implementation>
<method name="computeSizes">
<body>
<![CDATA[
var kids = this._getRadioChildren();
for (var i = 0; i < kids.length; ++i)
kids[i].expandedHeight = kids[i]._content.boxObject.height;
this.removeAttribute("_uninitialized");
]]>
</body>
</method>
<field name="lastSelectedItem">null</field>
</implementation>
</binding>
<binding id="updateCategory" extends="chrome://global/content/bindings/radio.xml#radio">
<resources>
<stylesheet src="chrome://global/skin/radio.css"/>
<stylesheet src="chrome://mozapps/skin/update/update.css"/>
</resources>
<content>
<xul:hbox class="updateCategoryBox" xbl:inherits="selected,checked,disabled">
#ifdef MOZ_WIDGET_GTK2
<xul:hbox class="radio-spacer-box">
#endif
<xul:hbox class="radio-check-box1" xbl:inherits="selected,checked,disabled">
<xul:hbox class="radio-check-box2" flex="1">
<xul:image class="radio-check" xbl:inherits="selected,checked,disabled"/>
</xul:hbox>
</xul:hbox>
#ifdef MOZ_WIDGET_GTK2
</xul:hbox>
#endif
<xul:image class="updateCategoryIcon" xbl:inherits="src"/>
<xul:label class="updateCategoryLabel" xbl:inherits="xbl:text=label,accesskey,crop,selected" flex="1"/>
</xul:hbox>
<xul:vbox flex="1" class="updateCategoryContent">
<children/>
</xul:vbox>
</content>
<implementation implements="nsITimerCallback">
<property name="expandedHeight"
onget="return this.getAttribute('expandedHeight');"
onset="this.setAttribute('expandedHeight', val); return val;"/>
<method name="notify">
<parameter name="aTimer"/>
<body>
<![CDATA[
var newHeight;
if (this._destinationSize == 0) {
if (this._content.boxObject.height > 0) {
newHeight = this._content.boxObject.height - this._animateIncrement;
newHeight = newHeight < 0 ? 0 : newHeight;
this._content.style.height = newHeight + "px";
this._timer.initWithCallback(this, this._animateDelay,
Components.interfaces.nsITimer.TYPE_ONE_SHOT);
}
else {
this._timer.cancel();
this._content.style.visibility = "collapse";
}
}
else {
if (this._content.boxObject.height <= this._destinationSize) {
newHeight = this._content.boxObject.height + this._animateIncrement;
newHeight = newHeight > this.expandedHeight ? this.expandedHeight : newHeight;
this._content.style.height = newHeight + "px";
this._timer.initWithCallback(this, this._animateDelay,
Components.interfaces.nsITimer.TYPE_ONE_SHOT);
}
else
this._timer.cancel();
}
]]>
</body>
</method>
<method name="_setUpTimer">
<parameter name="aSelected"/>
<body>
<![CDATA[
if (!this._timer)
this._timer = Components.classes["@mozilla.org/timer;1"]
.createInstance(Components.interfaces.nsITimer);
else
this._timer.cancel();
this._content.style.visibility = "visible";
this._destinationSize = aSelected ? this.expandedHeight : 0;
this._timer.initWithCallback(this, this._animateDelay,
Components.interfaces.nsITimer.TYPE_ONE_SHOT);
]]>
</body>
</method>
<field name="_content">
document.getAnonymousElementByAttribute(this, "class", "updateCategoryContent");
</field>
<field name="_timer">null</field>
<field name="_animateDelay">50</field>
<field name="_animateIncrement">25</field>
<field name="_destinationSize">0</field>
</implementation>
<handlers>
<handler event="RadioStateChange">
<![CDATA[
/*
this._content.style.height = "0px";
if (this.radioGroup.lastSelectedItem)
this.radioGroup.lastSelectedItem._setUpTimer(false);
this.radioGroup.lastSelectedItem = this;
this._setUpTimer(true);*/
]]>
</handler>
</handlers>
</binding>
<binding id="updateItem" extends="chrome://global/content/bindings/checkbox.xml#checkbox">
<content>
#ifdef MOZ_WIDGET_GTK2
<xul:hbox class="checkbox-spacer-box">
#endif
<xul:image class="checkbox-check" xbl:inherits="checked,disabled"/>
#ifdef MOZ_WIDGET_GTK2
</xul:hbox>
<xul:hbox class="checkbox-label-center-box" flex="1">
#endif
<xul:hbox class="checkbox-label-box" flex="1">
<xul:label class="checkbox-label foundLabel" xbl:inherits="xbl:text=label,accesskey" flex="1"/>
<xul:label class="checkbox-label" value="&from.label;"/>
<xul:label class="checkbox-label foundSource" xbl:inherits="xbl:text=source,infoURL,accesskey,crop"/>
</xul:hbox>
#ifdef MOZ_WIDGET_GTK2
</xul:hbox>
#endif
</content>
<implementation>
<property name="type"
onget="return this.getAttribute('type');"
onset="this.setAttribute('type', val); return val;"/>
<property name="source"
onget="return this.getAttribute('source');"
onset="this.setAttribute('source', val); return val;"/>
<property name="URL"
onget="return this.getAttribute('URL');"
onset="this.setAttribute('URL', val); return val;"/>
<property name="infoURL"
onget="return this.getAttribute('infoURL');"
onset="this.setAttribute('infoURL', val); return val;"/>
<property name="internalName"
onget="return this.getAttribute('internalName');"
onset="this.setAttribute('internalName', val); return val;"/>
</implementation>
</binding>
<binding id="link" extends="chrome://global/content/bindings/text.xml#text-base">
<content>
<xul:label xbl:inherits="value=label,crop" class="linkLabel" flex="1"/>
</content>
<implementation>
<property name="href"
onget="return this.getAttribute('href');"
onset="this.setAttribute('href', val); return val;"/>
</implementation>
<handlers>
<handler event="keypress" keycode="VK_ENTER" action="this.click()" />
<handler event="keypress" keycode="VK_RETURN" action="this.click()" />
<handler event="click">
<![CDATA[
if (event.button != 0)
return;
# If we're not a browser, use the external protocol service to load the URI.
#ifndef MOZ_PHOENIX
var uri = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(this.getAttribute("href"), null, null);
var protocolSvc = Components.classes["@mozilla.org/uriloader/external-protocol-service;1"]
.getService(Components.interfaces.nsIExternalProtocolService);
if (protocolSvc.isExposedProtocol(uri.scheme))
protocolSvc.loadUrl(uri);
# If we're a browser, open a new browser window instead.
#else
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher);
var ary = Components.classes["@mozilla.org/supports-array;1"]
.createInstance(Components.interfaces.nsISupportsArray);
var url = Components.classes["@mozilla.org/supports-string;1"]
.createInstance(Components.interfaces.nsISupportsString);
url.data = this.getAttribute("href")
ary.AppendElement(url);
ww.openWindow(null, "chrome://browser/content/browser.xul",
"_blank", "chrome,all,dialog=no", ary);
#endif
]]>
</handler>
</handlers>
</binding>
</bindings>

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

@ -372,7 +372,7 @@ interface nsIExtensionManager : nsISupports
* XXXben work in progress, the name of this interface will change after the
* update system is complete, probably to nsIAddon
*/
[scriptable, uuid(415edb0a-4f2d-485c-9e10-f262b065ab33)]
[scriptable, uuid(7f952767-427f-402b-8114-f80c95d1980d)]
interface nsIUpdateItem : nsISupports
{
/**
@ -412,6 +412,13 @@ interface nsIUpdateItem : nsISupports
*/
readonly attribute AString xpiURL;
/**
* The string Hash for the XPI file. Can be null and if supplied must be in
* the format of "type:hash" (see the types in nsICryptoHash and
* nsIXPInstallManager::initManagerWithHashes).
*/
readonly attribute AString xpiHash;
/**
* The URL of the icon that can be shown for this item.
*/
@ -442,7 +449,7 @@ interface nsIUpdateItem : nsISupports
void init(in AString id, in AString version,
in AString installLocationKey, in AString minAppVersion,
in AString maxAppVersion, in AString name,
in AString downloadURL, in AString iconURL,
in AString downloadURL, in AString xpiHash, in AString iconURL,
in AString updateURL, in long type);
/**

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

@ -287,11 +287,11 @@ function getResourceForID(id) {
* ...
*/
function makeItem(id, version, locationKey, minVersion, maxVersion, name,
updateURL, iconURL, updateRDF, type) {
updateURL, updateHash, iconURL, updateRDF, type) {
var item = Components.classes["@mozilla.org/updates/item;1"]
.createInstance(Components.interfaces.nsIUpdateItem);
item.init(id, version, locationKey, minVersion, maxVersion, name,
updateURL, iconURL, updateRDF, type);
updateURL, updateHash, iconURL, updateRDF, type);
return item;
}
@ -2501,6 +2501,7 @@ ExtensionManager.prototype = {
targetAppInfo ? targetAppInfo.maxVersion : "",
getManifestProperty(installManifest, "name"),
"", /* XPI Update URL */
"", /* XPI Update Hash */
getManifestProperty(installManifest, "iconURL"),
getManifestProperty(installManifest, "updateURL"),
installData.type);
@ -3849,7 +3850,10 @@ ExtensionManager.prototype = {
aInstallLocationKey,
installData.currentApp.minVersion,
installData.currentApp.maxVersion,
installData.name, "", "",
installData.name,
"", /* XPI Update URL */
"", /* XPI Update Hash */
"", /* Icon URL */
installData.updateURL || "",
installData.type);
em.update([item], 1, true, this);
@ -4121,6 +4125,7 @@ ExtensionManager.prototype = {
installLocation : EM_L(installLocation.name),
type : EM_I(type),
availableUpdateURL : null,
availableUpdateHash : null,
availableUpdateVersion: null };
for (var p in props)
ds.setItemProperty(id, EM_R(p), props[p]);
@ -4160,6 +4165,7 @@ ExtensionManager.prototype = {
var props = { installLocation : EM_L(installLocation.name),
type : EM_I(type),
availableUpdateURL : null,
availableUpdateHash : null,
availableUpdateVersion : null };
for (var p in props)
ds.setItemProperty(id, EM_R(p), props[p]);
@ -4683,6 +4689,7 @@ ExtensionManager.prototype = {
this._downloadCount += itemCount;
var urls = [];
var hashes = [];
var txn = new ItemDownloadTransaction(this);
for (var i = 0; i < itemCount; ++i) {
var currItem = items[i];
@ -4690,6 +4697,7 @@ ExtensionManager.prototype = {
txn.addDownload(currItem, txnID);
this._transactions.push(txn);
urls.push(currItem.xpiURL);
hashes.push(currItem.xpiHash);
}
// Kick off the download process for this transaction
@ -4701,7 +4709,7 @@ ExtensionManager.prototype = {
var xpimgr =
Components.classes["@mozilla.org/xpinstall/install-manager;1"].
createInstance(Components.interfaces.nsIXPInstallManager);
xpimgr.initManagerFromChrome(urls, urls.length, txn);
xpimgr.initManagerWithHashes(urls, hashes, urls.length, txn);
}
else
gOS.notifyObservers(txn, "xpinstall-progress", "open");
@ -5386,7 +5394,7 @@ RDFItemUpdater.prototype = {
// Parse the response RDF
function UpdateData() {};
UpdateData.prototype = { version: "0.0", updateLink: null,
UpdateData.prototype = { version: "0.0", updateLink: null, updateHash: null,
minVersion: "0.0", maxVersion: "0.0" };
var versionUpdate = new UpdateData();
@ -5414,7 +5422,10 @@ RDFItemUpdater.prototype = {
newestUpdate.minVersion,
newestUpdate.maxVersion,
aLocalItem.name,
newestUpdate.updateLink, "", "",
newestUpdate.updateLink,
newestUpdate.updateHash,
"", /* Icon URL */
"", /* RDF Update URL */
aLocalItem.type);
if (this._updater._isValidUpdate(aLocalItem, newerItem))
++this._updater._updateCount;
@ -5436,8 +5447,11 @@ RDFItemUpdater.prototype = {
aLocalItem.installLocationKey,
versionUpdate.minVersion,
versionUpdate.maxVersion,
aLocalItem.name,
"", "", "",
aLocalItem.name,
"", /* XPI Update URL */
"", /* XPI Update Hash */
"", /* Icon URL */
"", /* RDF Update URL */
aLocalItem.type);
if (this._updater._isValidUpdate(aLocalItem, sameItem)) {
// Install-time updates are not written to the DS because there is no
@ -5565,6 +5579,7 @@ RDFItemUpdater.prototype = {
if (aVersionUpdatesOnly ? result == 0 : result > 0) {
aUpdateData.version = version;
aUpdateData.updateLink = this._getPropertyFromResource(aDataSource, targetApp, "updateLink", aLocalItem);
aUpdateData.updateHash = this._getPropertyFromResource(aDataSource, targetApp, "updateHash", aLocalItem);
aUpdateData.minVersion = this._getPropertyFromResource(aDataSource, targetApp, "minVersion", aLocalItem);
aUpdateData.maxVersion = this._getPropertyFromResource(aDataSource, targetApp, "maxVersion", aLocalItem);
}
@ -5747,6 +5762,7 @@ ExtensionsDataSource.prototype = {
return null;
var targetAppInfo = this.getTargetApplicationInfo(id, this);
var updateHash = this.getItemProperty(id, "availableUpdateHash");
return makeItem(id,
this.getItemProperty(id, "version"),
this.getItemProperty(id, "installLocation"),
@ -5754,6 +5770,7 @@ ExtensionsDataSource.prototype = {
targetAppInfo ? targetAppInfo.maxVersion : "",
this.getItemProperty(id, "name"),
this.getItemProperty(id, "availableUpdateURL"),
updateHash ? updateHash : "",
this.getItemProperty(id, "iconURL"),
this.getItemProperty(id, "updateURL"),
this.getItemProperty(id, "type"));
@ -6483,15 +6500,18 @@ ExtensionsDataSource.prototype = {
onAddonUpdateEnded: function(addon, status) {
LOG("Datasource: Addon Update Ended: " + addon.id + ", status: " + status);
this._updateURLs[addon.id] = status;
var url = null, version = null;
var url = null, hash = null, version = null;
var updateAvailable = status == nsIAddonUpdateCheckListener.STATUS_UPDATE;
if (updateAvailable) {
url = EM_L(addon.xpiURL);
if (addon.xpiHash)
hash = EM_L(addon.xpiHash);
version = EM_L(addon.version);
}
this.setItemProperty(addon.id, EM_R("availableUpdateURL"), url);
this.updateProperty(addon.id, "availableUpdateURL");
this.setItemProperty(addon.id, EM_R("availableUpdateHash"), hash);
this.setItemProperty(addon.id, EM_R("availableUpdateVersion"), version);
this.updateProperty(addon.id, "availableUpdateURL");
this.updateProperty(addon.id, "displayDescription");
},
@ -7015,7 +7035,7 @@ UpdateItem.prototype = {
* See nsIUpdateService.idl
*/
init: function(id, version, installLocationKey, minAppVersion, maxAppVersion,
name, downloadURL, iconURL, updateURL, type) {
name, downloadURL, xpiHash, iconURL, updateURL, type) {
this._id = id;
this._version = version;
this._installLocationKey = installLocationKey;
@ -7023,6 +7043,7 @@ UpdateItem.prototype = {
this._maxAppVersion = maxAppVersion;
this._name = name;
this._downloadURL = downloadURL;
this._xpiHash = xpiHash;
this._iconURL = iconURL;
this._updateURL = updateURL;
this._type = type;
@ -7038,6 +7059,7 @@ UpdateItem.prototype = {
get maxAppVersion() { return this._maxAppVersion; },
get name() { return this._name; },
get xpiURL() { return this._downloadURL; },
get xpiHash() { return this._xpiHash; },
get iconURL() { return this._iconURL },
get updateRDF() { return this._updateURL; },
get type() { return this._type; },
@ -7053,6 +7075,7 @@ UpdateItem.prototype = {
maxAppVersion : this._maxAppVersion,
name : this._name,
xpiURL : this._downloadURL,
xpiHash : this._xpiHash,
iconURL : this._iconURL,
updateRDF : this._updateURL,
type : this._type