Browse Source

fix: savePage throw on relative paths (#33017)

Shelley Vohr 3 years ago
parent
commit
f92f97972a

+ 1 - 1
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.

+ 5 - 0
shell/browser/api/electron_api_web_contents.cc

@@ -2315,6 +2315,11 @@ v8::Local<v8::Promise> WebContents::SavePage(
   gin_helper::Promise<void> promise(isolate);
   v8::Local<v8::Promise> 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);
 

+ 42 - 6
spec-main/api-browser-window-spec.ts

@@ -3410,20 +3410,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');