Forráskód Böngészése

use a random number as session id when getting frame contents

Gildas 5 éve
szülő
commit
3d0bc4cf9f

+ 5 - 0
extension/core/content/content-bootstrap.js

@@ -125,15 +125,20 @@ this.singlefile.extension.core.content.bootstrap = this.singlefile.extension.cor
 				await autoSavePage();
 			} else {
 				let frames = [];
+				let framesSessionId;
 				autoSaveTimeout = null;
 				if (!options.removeFrames && singlefile.lib.processors.frameTree.content.frames && window.frames && window.frames.length) {
 					frames = await singlefile.lib.processors.frameTree.content.frames.getAsync(options);
 				}
+				framesSessionId = frames && frames.sessionId;
 				if (options.userScriptEnabled && helper.waitForUserScript) {
 					await helper.waitForUserScript(helper.ON_BEFORE_CAPTURE_EVENT_NAME);
 				}
 				const docData = helper.preProcessDoc(document, window, options);
 				savePage(docData, frames);
+				if (framesSessionId) {
+					singlefile.lib.processors.frameTree.content.frames.cleanup(framesSessionId);
+				}
 				helper.postProcessDoc(document, docData.markedElements);
 				if (options.userScriptEnabled && helper.waitForUserScript) {
 					await helper.waitForUserScript(helper.ON_AFTER_CAPTURE_EVENT_NAME);

+ 4 - 2
extension/core/content/content-main.js

@@ -106,6 +106,7 @@ this.singlefile.extension.core.content.main = this.singlefile.extension.core.con
 
 	async function processPage(options) {
 		const frames = singlefile.lib.processors.frameTree.content.frames;
+		let framesSessionId;
 		singlefile.lib.helper.initDoc(document);
 		ui.onStartPage(options);
 		processor = new singlefile.lib.SingleFile(options);
@@ -184,6 +185,7 @@ this.singlefile.extension.core.content.main = this.singlefile.extension.core.con
 			};
 			preInitializationAllPromises.then(() => resolve(preInitializationAllPromises));
 		});
+		framesSessionId = options.frames && options.frames.sessionId;
 		const selectedFrame = options.frames && options.frames.find(frameData => frameData.requestedFrame);
 		options.win = window;
 		if (selectedFrame) {
@@ -203,8 +205,8 @@ this.singlefile.extension.core.content.main = this.singlefile.extension.core.con
 		if (!processor.cancelled) {
 			await processor.run();
 		}
-		if (!options.saveRawPage && !options.removeFrames && frames) {
-			frames.cleanup(options);
+		if (framesSessionId) {
+			frames.cleanup(framesSessionId);
 		}
 		let page;
 		if (!processor.cancelled) {

+ 4 - 2
lib/single-file/index.js

@@ -40,6 +40,7 @@ this.singlefile = this.singlefile || {
 		modules: {},
 		async getPageData(options = {}, initOptions, doc = window.document, win = window) {
 			const frames = this.processors.frameTree.content.frames;
+			let framesSessionId;
 			this.main.init(initOptions);
 			if (doc && window) {
 				this.helper.initDoc(doc);
@@ -59,6 +60,7 @@ this.singlefile = this.singlefile || {
 					}
 				}
 				[options.frames] = await Promise.all(preInitializationPromises);
+				framesSessionId = options.frames && options.frames.sessionId;
 			}
 			options.doc = doc;
 			options.win = win;
@@ -73,8 +75,8 @@ this.singlefile = this.singlefile || {
 			};
 			const processor = new this.SingleFile(options);
 			await processor.run();
-			if (!options.saveRawPage && !options.removeFrames && frames) {
-				frames.cleanup(options);
+			if (framesSessionId) {
+				frames.cleanup(framesSessionId);
 			}
 			return await processor.getPageData();
 		}

+ 27 - 9
lib/single-file/processors/frame-tree/content/content-frame-tree.js

@@ -86,7 +86,7 @@ this.singlefile.lib.processors.frameTree.content.frames = this.singlefile.lib.pr
 				createFrameResponseTimeout(message.sessionId, message.windowId);
 			} else if (message.method == CLEANUP_REQUEST_MESSAGE) {
 				cleanupRequest(message);
-			} else if ((!browser || !browser.runtime) && message.method == INIT_RESPONSE_MESSAGE) {
+			} else if (message.method == INIT_RESPONSE_MESSAGE && sessions.get(message.sessionId)) {
 				const port = event.ports[0];
 				port.onmessage = event => initResponse(event.data);
 			}
@@ -94,28 +94,46 @@ this.singlefile.lib.processors.frameTree.content.frames = this.singlefile.lib.pr
 	}, true);
 	return {
 		getAsync: options => {
-			const sessionId = options.sessionId || 0;
+			const sessionId = getNewSessionId();
 			options = JSON.parse(JSON.stringify(options));
 			return new Promise(resolve => {
-				sessions.set(sessionId, { frames: [], requestTimeouts: {}, responseTimeouts: {}, resolve });
+				sessions.set(sessionId, {
+					frames: [],
+					requestTimeouts: {},
+					responseTimeouts: {},
+					resolve: frames => {
+						frames.sessionId = sessionId;
+						resolve(frames);
+					}
+				});
 				initRequestAsync({ windowId, sessionId, options });
 			});
 		},
 		getSync: options => {
-			const sessionId = options.sessionId || 0;
+			const sessionId = getNewSessionId();
 			options = JSON.parse(JSON.stringify(options));
-			sessions.set(sessionId, { frames: [], requestTimeouts: {}, responseTimeouts: {} });
+			sessions.set(sessionId, {
+				frames: [],
+				requestTimeouts: {},
+				responseTimeouts: {}
+			});
 			initRequestSync({ windowId, sessionId, options });
-			return sessions.get(sessionId).frames;
+			const frames = sessions.get(sessionId).frames;
+			frames.sessionId = sessionId;
+			return frames;
 		},
-		cleanup: options => {
-			const sessionId = options.sessionId || 0;
+		cleanup: sessionId => {
+			sessions.delete(sessionId);
 			cleanupRequest({ windowId, sessionId, options: { sessionId } });
 		},
 		initResponse,
 		TIMEOUT_INIT_REQUEST_MESSAGE
 	};
 
+	function getNewSessionId() {
+		return window.crypto.getRandomValues(new Uint32Array(32)).join("");
+	}
+
 	function initRequestSync(message) {
 		const waitForUserScript = singlefile.lib.helper.waitForUserScript;
 		const sessionId = message.sessionId;
@@ -325,7 +343,7 @@ this.singlefile.lib.processors.frameTree.content.frames = this.singlefile.lib.pr
 		} else {
 			if (useChannel) {
 				const channel = new MessageChannel();
-				targetWindow.postMessage(MESSAGE_PREFIX + JSON.stringify({ method: message.method }), TARGET_ORIGIN, [channel.port2]);
+				targetWindow.postMessage(MESSAGE_PREFIX + JSON.stringify({ method: message.method, sessionId: message.sessionId }), TARGET_ORIGIN, [channel.port2]);
 				channel.port1.postMessage(message);
 			} else {
 				targetWindow.postMessage(MESSAGE_PREFIX + JSON.stringify(message), TARGET_ORIGIN);

+ 1 - 5
lib/single-file/single-file-core.js

@@ -25,7 +25,7 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
 
 	const DEBUG = false;
 
-	let util, cssTree, sessionId = 0;
+	let util, cssTree;
 
 	function getClass(...args) {
 		[util, cssTree] = args;
@@ -35,10 +35,6 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
 	class SingleFileClass {
 		constructor(options) {
 			this.options = options;
-			if (options.sessionId === undefined) {
-				options.sessionId = sessionId;
-				sessionId++;
-			}
 		}
 		async run() {
 			if (this.options.userScriptEnabled) {