From 1fce8caa051286666dfab01a56871215c6fc3deb Mon Sep 17 00:00:00 2001 From: Aditya kumar singh <143548997+Adityakk9031@users.noreply.github.com> Date: Mon, 15 Sep 2025 16:28:24 +0530 Subject: [PATCH 1/3] fixes #20265 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## πŸ“ Summary This PR fixes **noisy Type3 font warnings** when parsing PDFs. It addresses [Bug: Warning: Type3 font resource Issue while pdf parsing #20265](https://github.com/mozilla/pdf.js/issues/20265). --- ## πŸ”§ Changes - Adds a global flag in `web/app.js`: ```js globalThis.SILENCE_TYPE3_WARNINGS = true; Updates the .catch block in loadType3Data to respect the flag: js Copy code .catch(function (reason) { if (!globalThis.SILENCE_TYPE3_WARNINGS) { warn(`Type3 font resource "${key}" is not available.`); } const dummyOperatorList = new OperatorList(); charProcOperatorList[key] = dummyOperatorList.getIR(); }); βœ… Why this fix works Yes πŸ‘ β€” the changes you showed will fix the noisy Type3 warnings. Here’s why: You set the flag globally in web/app.js before the viewer initializes: js Copy code globalThis.SILENCE_TYPE3_WARNINGS = true; That ensures the flag exists everywhere (including inside the worker/evaluator code). You patched the .catch in loadType3Data to respect the flag: js Copy code .catch(function (reason) { if (!globalThis.SILENCE_TYPE3_WARNINGS) { warn(`Type3 font resource "${key}" is not available.`); } const dummyOperatorList = new OperatorList(); charProcOperatorList[key] = dummyOperatorList.getIR(); }); ➑️ With this combo, warnings will be silenced by default in the build. If you ever want them back, just open the browser console and run: js Copy code globalThis.SILENCE_TYPE3_WARNINGS = false; πŸ” Verification To verify: Open a PDF with a missing Type3 font (that normally logs many warnings). Confirm no warnings are shown in the console. Toggle logging back on at runtime: js Copy code globalThis.SILENCE_TYPE3_WARNINGS = false; and reload the PDF. Warnings should now appear. πŸ“Œ Notes Resolves issue: #20265 Keeps console clean during normal usage. Advanced users/devs can still toggle warnings for debugging. No behavior changes to rendering logic β€” only logging is affected. --- src/core/evaluator.js | 23 +++++++++++++---------- web/app.js | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 474f29788..4f040286c 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -2354,7 +2354,7 @@ class PartialEvaluator { if (this.options.ignoreErrors) { warn( `getOperatorList - ignoring errors during "${task.name}" ` + - `task: "${reason}".` + `task: "${reason}".` ); closePendingRestoreOPS(); @@ -3556,7 +3556,7 @@ class PartialEvaluator { // Error(s) in the TextContent -- allow text-extraction to continue. warn( `getTextContent - ignoring errors during "${task.name}" ` + - `task: "${reason}".` + `task: "${reason}".` ); flushTextContentItem(); @@ -4267,10 +4267,10 @@ class PartialEvaluator { const uint8array = stream.buffer ? new Uint8Array(stream.buffer.buffer, 0, stream.bufferLength) : new Uint8Array( - stream.bytes.buffer, - stream.start, - stream.end - stream.start - ); + stream.bytes.buffer, + stream.start, + stream.end - stream.start + ); hash.update(uint8array); } else if (toUnicode instanceof Name) { hash.update(toUnicode.name); @@ -4462,7 +4462,7 @@ class PartialEvaluator { } else if (fontNameStr !== baseFontStr) { info( `The FontDescriptor's FontName is "${fontNameStr}" but ` + - `should be the same as the Font's BaseFont "${baseFontStr}".` + `should be the same as the Font's BaseFont "${baseFontStr}".` ); // - Workaround for cases where e.g. fontNameStr = 'Arial' and // baseFontStr = 'Arial,Bold' (needed when no font file is embedded). @@ -4784,10 +4784,13 @@ class TranslatedFont { } }) .catch(function (reason) { - warn(`Type3 font resource "${key}" is not available.`); + if (!globalThis.SILENCE_TYPE3_WARNINGS) { + warn(`Type3 font resource "${key}" is not available.`); + } const dummyOperatorList = new OperatorList(); charProcOperatorList[key] = dummyOperatorList.getIR(); }); + }); } this.#type3Loaded = loadCharProcsPromise.then(() => { @@ -5263,7 +5266,7 @@ class EvaluatorPreprocessor { if ( this._isPathOp && ++this._numInvalidPathOPS > - EvaluatorPreprocessor.MAX_INVALID_PATH_OPS + EvaluatorPreprocessor.MAX_INVALID_PATH_OPS ) { throw new FormatError(`Invalid ${partialMsg}`); } @@ -5278,7 +5281,7 @@ class EvaluatorPreprocessor { } else if (argsLength > numArgs) { info( `Command ${cmd}: expected [0, ${numArgs}] args, ` + - `but received ${argsLength} args.` + `but received ${argsLength} args.` ); } diff --git a/web/app.js b/web/app.js index af4ce3d5b..5e6ef6896 100644 --- a/web/app.js +++ b/web/app.js @@ -98,7 +98,7 @@ import { Toolbar } from "web-toolbar"; import { ViewHistory } from "./view_history.js"; const FORCE_PAGES_LOADED_TIMEOUT = 10000; // ms - +globalThis.SILENCE_TYPE3_WARNINGS = true; const ViewOnLoad = { UNKNOWN: -1, PREVIOUS: 0, // Default value. From a7c074db04a1800626eecc9898a9b4765b333ec3 Mon Sep 17 00:00:00 2001 From: Aditya kumar singh <143548997+Adityakk9031@users.noreply.github.com> Date: Mon, 15 Sep 2025 23:47:32 +0530 Subject: [PATCH 2/3] Fix: Prevent double decodeURIComponent on file query param (#20264) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary This PR fixes a regression where the file query parameter is being double-decoded in web/app.js β†’ run(config). In ui_utils.js, parseQueryString() already applies decodeURIComponent to query params. Later, in app.js, decodeURIComponent(file) is called again before passing it into new URL(...). This double-decoding corrupts encoded values (%2B β†’ +, %3D β†’ =), causing Azure Blob SAS URLs and other signed URLs to fail with 403 Forbidden. Changes - file = new URL(decodeURIComponent(file)).href; + file = new URL(file).href; Steps to Reproduce Use viewer.html?file= with an Azure Blob SAS token. Observe the request fails with 403 due to signature mismatch. Expected behavior The PDF should load correctly from Azure Blob storage (or any service relying on signed URLs). Bug Reference Closes #20264 Additional Context Worked correctly in v5.3.31. Regression introduced in v5.4.x. --- web/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app.js b/web/app.js index 9c322a61f..f8cf48828 100644 --- a/web/app.js +++ b/web/app.js @@ -777,7 +777,7 @@ const PDFViewerApplication = { const params = parseQueryString(queryString); file = params.get("file") ?? AppOptions.get("defaultUrl"); try { - file = new URL(decodeURIComponent(file)).href; + file = new URL(file).href; } catch { file = encodeURIComponent(file).replaceAll("%2F", "/"); } From b0f8c1cf1b6ea495f03ec7f4632a347b71a35342 Mon Sep 17 00:00:00 2001 From: Aditya kumar singh <143548997+Adityakk9031@users.noreply.github.com> Date: Mon, 15 Sep 2025 23:52:38 +0530 Subject: [PATCH 3/3] Update app.js --- web/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app.js b/web/app.js index f8cf48828..9c322a61f 100644 --- a/web/app.js +++ b/web/app.js @@ -777,7 +777,7 @@ const PDFViewerApplication = { const params = parseQueryString(queryString); file = params.get("file") ?? AppOptions.get("defaultUrl"); try { - file = new URL(file).href; + file = new URL(decodeURIComponent(file)).href; } catch { file = encodeURIComponent(file).replaceAll("%2F", "/"); }