Created
April 18, 2026 20:31
-
-
Save eliandoran/449c4f80a01a65b5a4c5ed3eeb92ff0f to your computer and use it in GitHub Desktop.
PDF generation broken after an invalid range
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>printToPDF Repro</title> | |
| <style> | |
| body { font-family: system-ui; padding: 20px; } | |
| #log { white-space: pre-wrap; font-family: monospace; background: #f0f0f0; padding: 12px; margin-top: 16px; border-radius: 4px; max-height: 400px; overflow-y: auto; } | |
| button { margin: 4px; padding: 8px 16px; cursor: pointer; } | |
| .pass { color: green; } .fail { color: red; } | |
| </style> | |
| </head> | |
| <body> | |
| <h2>Electron printToPDF — Page Range State Corruption Repro</h2> | |
| <p>Click <b>Run Test Sequence</b> to reproduce the bug. It will:</p> | |
| <ol> | |
| <li>Print with no page range (should succeed)</li> | |
| <li>Print with page range "999" (should fail — page doesn't exist)</li> | |
| <li>Print with no page range again (does it still work?)</li> | |
| </ol> | |
| <button id="run">Run Test Sequence</button> | |
| <button id="run-fresh">Run Step 3 Only (fresh, no prior failure)</button> | |
| <div id="log"></div> | |
| <script> | |
| const { ipcRenderer } = require("electron"); | |
| const logEl = document.getElementById("log"); | |
| function log(msg, cls) { | |
| const line = document.createElement("div"); | |
| line.textContent = msg; | |
| if (cls) line.className = cls; | |
| logEl.appendChild(line); | |
| logEl.scrollTop = logEl.scrollHeight; | |
| } | |
| async function runStep(step, pageRanges, description) { | |
| log(`\n--- Step ${step}: ${description} (pageRanges=${JSON.stringify(pageRanges)}) ---`); | |
| const result = await ipcRenderer.invoke("print-test", { pageRanges, step }); | |
| if (result.ok) { | |
| log(` ✓ SUCCESS (buffer: ${result.size} bytes)`, "pass"); | |
| } else { | |
| log(` ✗ FAILED: ${result.error}`, "fail"); | |
| } | |
| return result; | |
| } | |
| document.getElementById("run").addEventListener("click", async () => { | |
| logEl.textContent = ""; | |
| log("=== Test Sequence: state corruption after failed pageRanges ==="); | |
| await runStep(1, "", "No page range (baseline)"); | |
| await runStep(2, "999", "Invalid page range (expect failure)"); | |
| await runStep(3, "", "No page range again (does state persist?)"); | |
| log("\n=== Done ==="); | |
| log("If Step 3 fails with 'Page range exceeds page count',"); | |
| log("it confirms an Electron/Chromium state corruption bug."); | |
| }); | |
| document.getElementById("run-fresh").addEventListener("click", async () => { | |
| logEl.textContent = ""; | |
| log("=== Control: single call with no page range ==="); | |
| await runStep("C", "", "No page range (no prior failure)"); | |
| log("\n=== Done ==="); | |
| }); | |
| </script> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const { app, BrowserWindow, ipcMain } = require("electron"); | |
| let mainWindow; | |
| app.whenReady().then(() => { | |
| mainWindow = new BrowserWindow({ | |
| width: 800, | |
| height: 600, | |
| webPreferences: { | |
| nodeIntegration: true, | |
| contextIsolation: false, | |
| }, | |
| }); | |
| mainWindow.loadFile("index.html"); | |
| }); | |
| ipcMain.handle("print-test", async (_e, { pageRanges, step }) => { | |
| const printWindow = new BrowserWindow({ | |
| show: false, | |
| width: 1, | |
| height: 1, | |
| webPreferences: { offscreen: process.platform !== "linux" }, | |
| }); | |
| await printWindow.loadFile("print-page.html"); | |
| // Wait for content to be ready. | |
| await printWindow.webContents.executeJavaScript( | |
| `new Promise(r => requestAnimationFrame(() => requestAnimationFrame(r)))` | |
| ); | |
| const opts = { | |
| landscape: false, | |
| pageSize: "A4", | |
| scale: 1, | |
| printBackground: true, | |
| // Only include pageRanges if truthy (non-empty string). | |
| ...(pageRanges ? { pageRanges } : {}), | |
| }; | |
| console.log(`[Step ${step}] printToPDF called with:`, JSON.stringify(opts)); | |
| try { | |
| const buffer = await printWindow.webContents.printToPDF(opts); | |
| console.log(`[Step ${step}] SUCCESS - buffer size: ${buffer.length}`); | |
| printWindow.destroy(); | |
| return { ok: true, size: buffer.length }; | |
| } catch (err) { | |
| console.error(`[Step ${step}] FAILED: ${err.message}`); | |
| printWindow.destroy(); | |
| return { ok: false, error: err.message }; | |
| } | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "name": "material-variation-perfect-ub624", | |
| "productName": "material-variation-perfect-ub624", | |
| "description": "My Electron application description", | |
| "keywords": [], | |
| "main": "./main.js", | |
| "version": "1.0.0", | |
| "author": "elian", | |
| "scripts": { | |
| "start": "electron ." | |
| }, | |
| "dependencies": {}, | |
| "devDependencies": { | |
| "electron": "41.1.1" | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html> | |
| <head><title>Print Test</title></head> | |
| <body> | |
| <h1>Test Page</h1> | |
| <p>This is a single-page document used to reproduce the printToPDF bug.</p> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment