From 1e007f9285ad1ded6696baa4da86e5d3fbfecbb4 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sun, 6 Dec 2020 13:57:24 +0100 Subject: [PATCH] Actually remove a `scripting`-instance, and its global events, upon document closing I was actually quite surprised to find that, despite the various `scripting`-getters implementing `destroySandbox` methods, there were no attempts at actually cleaning-up either the "sandbox" or removing the globally registered event listeners. --- web/app.js | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/web/app.js b/web/app.js index d62cbf632..ff7aa9fb8 100644 --- a/web/app.js +++ b/web/app.js @@ -257,6 +257,7 @@ const PDFViewerApplication = { _saveInProgress: false, _wheelUnusedTicks: 0, _idleCallbacks: new Set(), + _scriptingInstance: null, // Called once when the document is loaded. async initialize(appConfig) { @@ -803,6 +804,18 @@ const PDFViewerApplication = { } this._idleCallbacks.clear(); + if (this._scriptingInstance) { + const { scripting, events } = this._scriptingInstance; + try { + scripting.destroySandbox(); + } catch (ex) {} + + for (const [name, listener] of events) { + window.removeEventListener(name, listener); + } + this._scriptingInstance = null; + } + this.pdfSidebar.reset(); this.pdfOutlineViewer.reset(); this.pdfAttachmentViewer.reset(); @@ -1423,6 +1436,9 @@ const PDFViewerApplication = { return; } const { scripting } = this.externalServices; + // Store a reference to the current scripting-instance, to allow destruction + // of the sandbox and removal of the event listeners at document closing. + this._scriptingInstance = { scripting, events: new Map() }; if (!this.documentInfo) { // It should be *extremely* rare for metadata to not have been resolved @@ -1439,7 +1455,7 @@ const PDFViewerApplication = { } } - window.addEventListener("updateFromSandbox", event => { + const updateFromSandbox = event => { const { detail } = event; const { id, command, value } = detail; if (!id) { @@ -1486,11 +1502,20 @@ const PDFViewerApplication = { pdfDocument.annotationStorage.setValue(id, value); } } - }); + }; + window.addEventListener("updateFromSandbox", updateFromSandbox); + // Ensure that the event listener can be removed at document closing. + this._scriptingInstance.events.set("updateFromSandbox", updateFromSandbox); - window.addEventListener("dispatchEventInSandbox", function (event) { + const dispatchEventInSandbox = event => { scripting.dispatchEventInSandbox(event.detail); - }); + }; + window.addEventListener("dispatchEventInSandbox", dispatchEventInSandbox); + // Ensure that the event listener can be removed at document closing. + this._scriptingInstance.events.set( + "dispatchEventInSandbox", + dispatchEventInSandbox + ); const dispatchEventName = generateRandomStringForSandbox(objects);