Browse Source

fix: validate `printToPDF` `margins` against `pageSize` (#41267)

Shelley Vohr 1 year ago
parent
commit
abd7850ee4
2 changed files with 25 additions and 1 deletions
  1. 11 1
      lib/browser/api/web-contents.ts
  2. 14 0
      spec/api-web-contents-spec.ts

+ 11 - 1
lib/browser/api/web-contents.ts

@@ -220,6 +220,16 @@ function parsePageSize (pageSize: string | ElectronInternal.PageSize) {
 let pendingPromise: Promise<any> | undefined;
 WebContents.prototype.printToPDF = async function (options) {
   const margins = checkType(options.margins ?? {}, 'object', 'margins');
+  const pageSize = parsePageSize(options.pageSize ?? 'letter');
+
+  const { top, bottom, left, right } = margins;
+  const validHeight = [top, bottom].every(u => u === undefined || u <= pageSize.paperHeight);
+  const validWidth = [left, right].every(u => u === undefined || u <= pageSize.paperWidth);
+
+  if (!validHeight || !validWidth) {
+    throw new Error('margins must be less than or equal to pageSize');
+  }
+
   const printSettings = {
     requestID: getNextId(),
     landscape: checkType(options.landscape ?? false, 'boolean', 'landscape'),
@@ -235,7 +245,7 @@ WebContents.prototype.printToPDF = async function (options) {
     pageRanges: checkType(options.pageRanges ?? '', 'string', 'pageRanges'),
     preferCSSPageSize: checkType(options.preferCSSPageSize ?? false, 'boolean', 'preferCSSPageSize'),
     generateTaggedPDF: checkType(options.generateTaggedPDF ?? false, 'boolean', 'generateTaggedPDF'),
-    ...parsePageSize(options.pageSize ?? 'letter')
+    ...pageSize
   };
 
   if (this._printToPDF) {

+ 14 - 0
spec/api-web-contents-spec.ts

@@ -2047,6 +2047,20 @@ describe('webContents module', () => {
       }
     });
 
+    it('rejects when margins exceed physical page size', async () => {
+      await w.loadURL('data:text/html,<h1>Hello, World!</h1>');
+
+      await expect(w.webContents.printToPDF({
+        pageSize: 'Letter',
+        margins: {
+          top: 100,
+          bottom: 100,
+          left: 5,
+          right: 5
+        }
+      })).to.eventually.be.rejectedWith('margins must be less than or equal to pageSize');
+    });
+
     it('does not crash when called multiple times in parallel', async () => {
       await w.loadURL('data:text/html,<h1>Hello, World!</h1>');