From 537ed37835a1df383153d16d5d267fa0f121cf1d Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Thu, 10 Mar 2022 13:37:21 +0100 Subject: [PATCH] Move the `isSameOrigin` helper function This function is currently placed in the `src/shared/util.js` file, which means that the code is duplicated in both of the *built* `pdf.js` and `pdf.worker.js` files. Furthermore, it only has a single call-site which is also specific to the `GENERIC`-build of the PDF.js library. Hence this helper function is instead moved into the `src/display/api.js` file, in such a way that it's conditionally defined but still can be unit-tested. --- src/display/api.js | 22 +++++++++++++++++++--- src/shared/util.js | 17 ----------------- test/unit/api_spec.js | 30 ++++++++++++++++++++++++++++++ test/unit/util_spec.js | 26 -------------------------- 4 files changed, 49 insertions(+), 46 deletions(-) diff --git a/src/display/api.js b/src/display/api.js index 241db612e..ca4752003 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -26,7 +26,6 @@ import { info, InvalidPDFException, isArrayBuffer, - isSameOrigin, MissingPDFException, PasswordException, RenderingIntentFlag, @@ -1959,7 +1958,7 @@ const PDFWorkerUtil = { fallbackWorkerSrc: null, fakeWorkerId: 0, }; -if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("GENERIC")) { +if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { // eslint-disable-next-line no-undef if (isNodeJS && typeof __non_webpack_require__ === "function") { // Workers aren't supported in Node.js, force-disabling them there. @@ -1978,6 +1977,22 @@ if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("GENERIC")) { } } + // Check if URLs have the same origin. For non-HTTP based URLs, returns false. + PDFWorkerUtil.isSameOrigin = function (baseUrl, otherUrl) { + let base; + try { + base = new URL(baseUrl); + if (!base.origin || base.origin === "null") { + return false; // non-HTTP url + } + } catch (e) { + return false; + } + + const other = new URL(otherUrl, base); + return base.origin === other.origin; + }; + PDFWorkerUtil.createCDNWrapper = function (url) { // We will rely on blob URL's property to specify origin. // We want this function to fail in case if createObjectURL or Blob do not @@ -2079,7 +2094,7 @@ class PDFWorker { if ( typeof PDFJSDev !== "undefined" && PDFJSDev.test("GENERIC") && - !isSameOrigin(window.location.href, workerSrc) + !PDFWorkerUtil.isSameOrigin(window.location.href, workerSrc) ) { workerSrc = PDFWorkerUtil.createCDNWrapper( new URL(workerSrc, window.location).href @@ -3370,6 +3385,7 @@ export { PDFDocumentProxy, PDFPageProxy, PDFWorker, + PDFWorkerUtil, RenderTask, setPDFNetworkStreamFactory, version, diff --git a/src/shared/util.js b/src/shared/util.js index cd93a2e16..e51f61735 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -411,22 +411,6 @@ function assert(cond, msg) { } } -// Checks if URLs have the same origin. For non-HTTP based URLs, returns false. -function isSameOrigin(baseUrl, otherUrl) { - let base; - try { - base = new URL(baseUrl); - if (!base.origin || base.origin === "null") { - return false; // non-HTTP url - } - } catch (e) { - return false; - } - - const other = new URL(otherUrl, base); - return base.origin === other.origin; -} - // Checks if URLs use one of the allowed protocols, e.g. to avoid XSS. function _isValidProtocol(url) { if (!url) { @@ -1133,7 +1117,6 @@ export { isAscii, IsEvalSupportedCached, IsLittleEndianCached, - isSameOrigin, MissingPDFException, objectFromMap, objectSize, diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index 273aa4be0..162621918 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -40,6 +40,7 @@ import { PDFDocumentProxy, PDFPageProxy, PDFWorker, + PDFWorkerUtil, RenderTask, } from "../../src/display/api.js"; import { @@ -2967,4 +2968,33 @@ Caron Broadcasting, Inc., an Ohio corporation (“Lessee”).`) } ); }); + + describe("PDFWorkerUtil", function () { + describe("isSameOrigin", function () { + const { isSameOrigin } = PDFWorkerUtil; + + it("handles invalid base URLs", function () { + // The base URL is not valid. + expect(isSameOrigin("/foo", "/bar")).toEqual(false); + + // The base URL has no origin. + expect(isSameOrigin("blob:foo", "/bar")).toEqual(false); + }); + + it("correctly checks if the origin of both URLs matches", function () { + expect( + isSameOrigin( + "https://www.mozilla.org/foo", + "https://www.mozilla.org/bar" + ) + ).toEqual(true); + expect( + isSameOrigin( + "https://www.mozilla.org/foo", + "https://www.example.com/bar" + ) + ).toEqual(false); + }); + }); + }); }); diff --git a/test/unit/util_spec.js b/test/unit/util_spec.js index b43b0ee7b..9ca4025ca 100644 --- a/test/unit/util_spec.js +++ b/test/unit/util_spec.js @@ -21,7 +21,6 @@ import { getModificationDate, isArrayBuffer, isAscii, - isSameOrigin, string32, stringToBytes, stringToPDFString, @@ -165,31 +164,6 @@ describe("util", function () { }); }); - describe("isSameOrigin", function () { - it("handles invalid base URLs", function () { - // The base URL is not valid. - expect(isSameOrigin("/foo", "/bar")).toEqual(false); - - // The base URL has no origin. - expect(isSameOrigin("blob:foo", "/bar")).toEqual(false); - }); - - it("correctly checks if the origin of both URLs matches", function () { - expect( - isSameOrigin( - "https://www.mozilla.org/foo", - "https://www.mozilla.org/bar" - ) - ).toEqual(true); - expect( - isSameOrigin( - "https://www.mozilla.org/foo", - "https://www.example.com/bar" - ) - ).toEqual(false); - }); - }); - describe("createValidAbsoluteUrl", function () { it("handles invalid URLs", function () { expect(createValidAbsoluteUrl(undefined, undefined)).toEqual(null);