From f16e3476727cbeff018e4f8a379dc97897fc54b9 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Thu, 3 Feb 2022 10:57:54 +0100 Subject: [PATCH] fix: savePage throw on relative paths --- docs/api/web-contents.md | 2 +- .../browser/api/electron_api_web_contents.cc | 5 ++ spec-main/api-browser-window-spec.ts | 48 ++++++++++++++++--- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 1dc00617c74e3..415d8af91cf34 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -1840,7 +1840,7 @@ the cursor when dragging. #### `contents.savePage(fullPath, saveType)` -* `fullPath` String - The full file path. +* `fullPath` String - The absolute file path. * `saveType` String - Specify the save type. * `HTMLOnly` - Save only the HTML of the page. * `HTMLComplete` - Save complete-html page. diff --git a/shell/browser/api/electron_api_web_contents.cc b/shell/browser/api/electron_api_web_contents.cc index b353075b1c672..8c1a125e93950 100644 --- a/shell/browser/api/electron_api_web_contents.cc +++ b/shell/browser/api/electron_api_web_contents.cc @@ -2315,6 +2315,11 @@ v8::Local WebContents::SavePage( gin_helper::Promise promise(isolate); v8::Local handle = promise.GetHandle(); + if (!full_file_path.IsAbsolute()) { + promise.RejectWithErrorMessage("Path must be absolute"); + return handle; + } + auto* handler = new SavePageHandler(web_contents(), std::move(promise)); handler->Handle(full_file_path, save_type); diff --git a/spec-main/api-browser-window-spec.ts b/spec-main/api-browser-window-spec.ts index b8ffaebff51f8..718e9b6e763ed 100644 --- a/spec-main/api-browser-window-spec.ts +++ b/spec-main/api-browser-window-spec.ts @@ -3394,20 +3394,56 @@ describe('BrowserWindow module', () => { const savePageJsPath = path.join(savePageDir, 'save_page_files', 'test.js'); const savePageCssPath = path.join(savePageDir, 'save_page_files', 'test.css'); - after(() => { + afterEach(() => { + closeAllWindows(); + try { fs.unlinkSync(savePageCssPath); fs.unlinkSync(savePageJsPath); fs.unlinkSync(savePageHtmlPath); fs.rmdirSync(path.join(savePageDir, 'save_page_files')); fs.rmdirSync(savePageDir); - } catch (e) { - // Ignore error - } + } catch {} + }); + + it('should throw when passing relative paths', async () => { + const w = new BrowserWindow({ show: false }); + await w.loadFile(path.join(fixtures, 'pages', 'save_page', 'index.html')); + + await expect( + w.webContents.savePage('save_page.html', 'HTMLComplete') + ).to.eventually.be.rejectedWith('Path must be absolute'); + + await expect( + w.webContents.savePage('save_page.html', 'HTMLOnly') + ).to.eventually.be.rejectedWith('Path must be absolute'); + + await expect( + w.webContents.savePage('save_page.html', 'MHTML') + ).to.eventually.be.rejectedWith('Path must be absolute'); + }); + + it('should save page to disk with HTMLOnly', async () => { + const w = new BrowserWindow({ show: false }); + await w.loadFile(path.join(fixtures, 'pages', 'save_page', 'index.html')); + await w.webContents.savePage(savePageHtmlPath, 'HTMLOnly'); + + expect(fs.existsSync(savePageHtmlPath)).to.be.true('html path'); + expect(fs.existsSync(savePageJsPath)).to.be.false('js path'); + expect(fs.existsSync(savePageCssPath)).to.be.false('css path'); + }); + + it('should save page to disk with MHTML', async () => { + const w = new BrowserWindow({ show: false }); + await w.loadFile(path.join(fixtures, 'pages', 'save_page', 'index.html')); + await w.webContents.savePage(savePageHtmlPath, 'MHTML'); + + expect(fs.existsSync(savePageHtmlPath)).to.be.true('html path'); + expect(fs.existsSync(savePageJsPath)).to.be.false('js path'); + expect(fs.existsSync(savePageCssPath)).to.be.false('css path'); }); - afterEach(closeAllWindows); - it('should save page to disk', async () => { + it('should save page to disk with HTMLComplete', async () => { const w = new BrowserWindow({ show: false }); await w.loadFile(path.join(fixtures, 'pages', 'save_page', 'index.html')); await w.webContents.savePage(savePageHtmlPath, 'HTMLComplete');