From 7b7c7c62516ad263053adeb37f555e5fee2cfd98 Mon Sep 17 00:00:00 2001 From: Lucas Fernandes Nogueira Date: Sun, 11 Oct 2026 16:11:59 -0300 Subject: [PATCH] fix(updater): release the previous download when downloading again (#3691) Each `Update.download()` overwrote `this.downloadedBytes` without closing the previous resource, so the whole previous update payload stayed in the webview resources table. The previous resource is now closed once the new download succeeded (so a failed retry still leaves the earlier download installable). Not covered by e2e: the fixture manifest has no valid signature, so a download can never succeed there. plugins/updater/guest-js/index.ts --- .changes/updater-js-redownload-leak.md | 6 ++++++ plugins/updater/api-iife.js | 2 +- plugins/updater/guest-js/index.ts | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .changes/updater-js-redownload-leak.md diff --git a/.changes/updater-js-redownload-leak.md b/.changes/updater-js-redownload-leak.md new file mode 100644 index 000000000..7e9dae62f --- /dev/null +++ b/.changes/updater-js-redownload-leak.md @@ -0,0 +1,6 @@ +--- +updater: patch +updater-js: patch +--- + +Calling `Update.download()` again now releases the bytes of the previous download instead of keeping them in memory until the webview is destroyed. diff --git a/plugins/updater/api-iife.js b/plugins/updater/api-iife.js index 242e6f07c..520d07189 100644 --- a/plugins/updater/api-iife.js +++ b/plugins/updater/api-iife.js @@ -1 +1 @@ -if("__TAURI__"in window){var __TAURI_PLUGIN_UPDATER__=function(e,n){"use strict";class t extends n.Resource{constructor(e){super(e.rid),this.available=!0,this.currentVersion=e.currentVersion,this.version=e.version,this.date=e.date,this.body=e.body,this.rawJson=e.rawJson}async download(e,t){a(t);const s=new n.Channel;e&&(s.onmessage=e);const d=await n.invoke("plugin:updater|download",{onEvent:s,rid:this.rid,...t});this.downloadedBytes=new n.Resource(d)}async install(e){if(!this.downloadedBytes)throw new Error("Update.install called before Update.download");await n.invoke("plugin:updater|install",{updateRid:this.rid,bytesRid:this.downloadedBytes.rid,...e}),this.downloadedBytes=void 0}async downloadAndInstall(e,t){a(t);const s=new n.Channel;e&&(s.onmessage=e),await n.invoke("plugin:updater|download_and_install",{onEvent:s,rid:this.rid,...t})}async close(){await(this.downloadedBytes?.close()),await super.close()}}function a(e){e?.headers&&(e.headers=Array.from(new Headers(e.headers).entries()))}return e.Update=t,e.check=async function(e){a(e);const s=await n.invoke("plugin:updater|check",{...e});return s?new t(s):null},e}({},window.__TAURI__.core);Object.defineProperty(window.__TAURI__,"updater",{value:__TAURI_PLUGIN_UPDATER__})} +if("__TAURI__"in window){var __TAURI_PLUGIN_UPDATER__=function(e,n){"use strict";class t extends n.Resource{constructor(e){super(e.rid),this.available=!0,this.currentVersion=e.currentVersion,this.version=e.version,this.date=e.date,this.body=e.body,this.rawJson=e.rawJson}async download(e,t){a(t);const s=new n.Channel;e&&(s.onmessage=e);const d=await n.invoke("plugin:updater|download",{onEvent:s,rid:this.rid,...t});await(this.downloadedBytes?.close().catch(()=>{})),this.downloadedBytes=new n.Resource(d)}async install(e){if(!this.downloadedBytes)throw new Error("Update.install called before Update.download");await n.invoke("plugin:updater|install",{updateRid:this.rid,bytesRid:this.downloadedBytes.rid,...e}),this.downloadedBytes=void 0}async downloadAndInstall(e,t){a(t);const s=new n.Channel;e&&(s.onmessage=e),await n.invoke("plugin:updater|download_and_install",{onEvent:s,rid:this.rid,...t})}async close(){await(this.downloadedBytes?.close()),await super.close()}}function a(e){e?.headers&&(e.headers=Array.from(new Headers(e.headers).entries()))}return e.Update=t,e.check=async function(e){a(e);const s=await n.invoke("plugin:updater|check",{...e});return s?new t(s):null},e}({},window.__TAURI__.core);Object.defineProperty(window.__TAURI__,"updater",{value:__TAURI_PLUGIN_UPDATER__})} diff --git a/plugins/updater/guest-js/index.ts b/plugins/updater/guest-js/index.ts index 4afbb0f56..f2b2dd519 100644 --- a/plugins/updater/guest-js/index.ts +++ b/plugins/updater/guest-js/index.ts @@ -165,6 +165,9 @@ class Update extends Resource { rid: this.rid, ...options }) + // release the bytes of a previous download, which would otherwise be kept + // in memory until the webview is destroyed + await this.downloadedBytes?.close().catch(() => {}) this.downloadedBytes = new Resource(downloadedBytesRid) }