Skip to content

Commit

Permalink
Merge pull request mozilla#18507 from Snuffleupagus/rm-PDFWorkerUtil
Browse files Browse the repository at this point in the history
Remove `PDFWorkerUtil` and move its contents into `PDFWorker` instead
  • Loading branch information
timvandermeij authored Jul 29, 2024
2 parents 582866e + c4fdb28 commit 300e806
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 78 deletions.
98 changes: 50 additions & 48 deletions src/display/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -1998,47 +1998,6 @@ class LoopbackPort {
* the constants from {@link VerbosityLevel} should be used.
*/

const PDFWorkerUtil = {
isWorkerDisabled: false,
fakeWorkerId: 0,
};
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
if (isNodeJS) {
// Workers aren't supported in Node.js, force-disabling them there.
PDFWorkerUtil.isWorkerDisabled = true;

GlobalWorkerOptions.workerSrc ||= PDFJSDev.test("LIB")
? "../pdf.worker.js"
: "./pdf.worker.mjs";
}

// 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 {
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
// exist or fail for some reason -- our Worker creation will fail anyway.
const wrapper = `await import("${url}");`;
return URL.createObjectURL(
new Blob([wrapper], { type: "text/javascript" })
);
};
}

/**
* PDF.js web worker abstraction that controls the instantiation of PDF
* documents. Message handlers are used to pass information from the main
Expand All @@ -2048,8 +2007,52 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
* @param {PDFWorkerParameters} params - The worker initialization parameters.
*/
class PDFWorker {
static #fakeWorkerId = 0;

static #isWorkerDisabled = false;

static #workerPorts;

static {
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
if (isNodeJS) {
// Workers aren't supported in Node.js, force-disabling them there.
this.#isWorkerDisabled = true;

GlobalWorkerOptions.workerSrc ||= PDFJSDev.test("LIB")
? "../pdf.worker.js"
: "./pdf.worker.mjs";
}

// Check if URLs have the same origin. For non-HTTP based URLs, returns
// false.
this._isSameOrigin = (baseUrl, otherUrl) => {
let base;
try {
base = new URL(baseUrl);
if (!base.origin || base.origin === "null") {
return false; // non-HTTP url
}
} catch {
return false;
}
const other = new URL(otherUrl, base);
return base.origin === other.origin;
};

this._createCDNWrapper = 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 exist or fail for some reason -- our Worker creation will fail
// anyway.
const wrapper = `await import("${url}");`;
return URL.createObjectURL(
new Blob([wrapper], { type: "text/javascript" })
);
};
}
}

constructor({
name = null,
port = null,
Expand Down Expand Up @@ -2138,7 +2141,7 @@ class PDFWorker {
// Right now, the requirement is, that an Uint8Array is still an
// Uint8Array as it arrives on the worker.
if (
PDFWorkerUtil.isWorkerDisabled ||
PDFWorker.#isWorkerDisabled ||
PDFWorker.#mainThreadWorkerMessageHandler
) {
this._setupFakeWorker();
Expand All @@ -2152,9 +2155,9 @@ class PDFWorker {
if (
typeof PDFJSDev !== "undefined" &&
PDFJSDev.test("GENERIC") &&
!PDFWorkerUtil.isSameOrigin(window.location.href, workerSrc)
!PDFWorker._isSameOrigin(window.location.href, workerSrc)
) {
workerSrc = PDFWorkerUtil.createCDNWrapper(
workerSrc = PDFWorker._createCDNWrapper(
new URL(workerSrc, window.location).href
);
}
Expand Down Expand Up @@ -2234,9 +2237,9 @@ class PDFWorker {
}

_setupFakeWorker() {
if (!PDFWorkerUtil.isWorkerDisabled) {
if (!PDFWorker.#isWorkerDisabled) {
warn("Setting up fake worker.");
PDFWorkerUtil.isWorkerDisabled = true;
PDFWorker.#isWorkerDisabled = true;
}

PDFWorker._setupFakeWorkerGlobal
Expand All @@ -2249,7 +2252,7 @@ class PDFWorker {
this._port = port;

// All fake workers use the same port, making id unique.
const id = `fake${PDFWorkerUtil.fakeWorkerId++}`;
const id = `fake${PDFWorker.#fakeWorkerId++}`;

// If the main thread is our worker, setup the handling for the
// messages -- the main thread sends to it self.
Expand Down Expand Up @@ -3470,7 +3473,6 @@ export {
PDFDocumentProxy,
PDFPageProxy,
PDFWorker,
PDFWorkerUtil,
RenderTask,
version,
};
55 changes: 25 additions & 30 deletions test/unit/api_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import {
PDFDocumentProxy,
PDFPageProxy,
PDFWorker,
PDFWorkerUtil,
RenderTask,
} from "../../src/display/api.js";
import {
Expand Down Expand Up @@ -929,6 +928,31 @@ describe("api", function () {
expect(typeof workerSrc).toEqual("string");
expect(workerSrc).toEqual(GlobalWorkerOptions.workerSrc);
});

describe("isSameOrigin", function () {
it("handles invalid base URLs", function () {
// The base URL is not valid.
expect(PDFWorker._isSameOrigin("/foo", "/bar")).toEqual(false);

// The base URL has no origin.
expect(PDFWorker._isSameOrigin("blob:foo", "/bar")).toEqual(false);
});

it("correctly checks if the origin of both URLs matches", function () {
expect(
PDFWorker._isSameOrigin(
"https://www.mozilla.org/foo",
"https://www.mozilla.org/bar"
)
).toEqual(true);
expect(
PDFWorker._isSameOrigin(
"https://www.mozilla.org/foo",
"https://www.example.com/bar"
)
).toEqual(false);
});
});
});

describe("GlobalWorkerOptions", function () {
Expand Down Expand Up @@ -4885,33 +4909,4 @@ 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);
});
});
});
});

0 comments on commit 300e806

Please sign in to comment.