[gnome-shell/gnome-3-36] extensionSystem: Prevent broken updates
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/gnome-3-36] extensionSystem: Prevent broken updates
- Date: Tue, 2 Jun 2020 23:43:48 +0000 (UTC)
commit 4220cd66249a93ee45bb05ba4def3db5cb6591a4
Author: Florian Müllner <fmuellner gnome org>
Date: Thu May 7 13:54:24 2020 +0200
extensionSystem: Prevent broken updates
Spidermonkey caches imports, which means that uninstalling an
old extension version and installing a new one doesn't work as
expected: If the previous version was loaded, then its code will
be imported instead.
For the last couple of releases this has been a reliable source
of extension bug reports after major GNOME updates. Thankfully
chrome-gnome-shell removed its update support in favor of our
built-in support now, but users may still use older versions
or perform those actions manually, so it still makes sense to
catch this case and set an appropriate error.
https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1248
js/ui/extensionSystem.js | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
---
diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js
index d8c16d91f3..7362a00e37 100644
--- a/js/ui/extensionSystem.js
+++ b/js/ui/extensionSystem.js
@@ -26,6 +26,7 @@ var ExtensionManager = class {
this._updateNotified = false;
this._extensions = new Map();
+ this._unloadedExtensions = new Map();
this._enabledExtensions = [];
this._extensionOrder = [];
@@ -319,6 +320,14 @@ var ExtensionManager = class {
return extension;
}
+ _canLoad(extension) {
+ if (!this._unloadedExtensions.has(extension.uuid))
+ return true;
+
+ const version = this._unloadedExtensions.get(extension.uuid);
+ return extension.metadata.version === version;
+ }
+
loadExtension(extension) {
// Default to error, we set success as the last step
extension.state = ExtensionState.ERROR;
@@ -327,6 +336,9 @@ var ExtensionManager = class {
if (checkVersion && ExtensionUtils.isOutOfDate(extension)) {
extension.state = ExtensionState.OUT_OF_DATE;
+ } else if (!this._canLoad(extension)) {
+ this.logExtensionError(extension.uuid, new Error(
+ 'A different version was loaded previously. You need to log out for changes to take
effect.'));
} else {
let enabled = this._enabledExtensions.includes(extension.uuid);
if (enabled) {
@@ -337,6 +349,8 @@ var ExtensionManager = class {
} else {
extension.state = ExtensionState.INITIALIZED;
}
+
+ this._unloadedExtensions.delete(extension.uuid);
}
this._updateCanChange(extension);
@@ -344,15 +358,22 @@ var ExtensionManager = class {
}
unloadExtension(extension) {
+ const { uuid, type } = extension;
+
// Try to disable it -- if it's ERROR'd, we can't guarantee that,
// but it will be removed on next reboot, and hopefully nothing
// broke too much.
- this._callExtensionDisable(extension.uuid);
+ this._callExtensionDisable(uuid);
extension.state = ExtensionState.UNINSTALLED;
this.emit('extension-state-changed', extension);
- this._extensions.delete(extension.uuid);
+ // If we did install an importer, it is now cached and it's
+ // impossible to load a different version
+ if (type === ExtensionType.PER_USER && extension.imports)
+ this._unloadedExtensions.set(uuid, extension.metadata.version);
+
+ this._extensions.delete(uuid);
return true;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]