From ae5a34c520e1548d6fc22ea0cc55ca542248cb0a Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Mon, 10 Feb 2020 13:54:09 +0100 Subject: [PATCH] [api-minor] Ensure that the `Array.prototype` doesn't contain any enumerable properties Over the years there's been a fair number of issues/PRs opened, where people have wanted to add `hasOwnProperty` checks in (hot) loops in the font parsing code. This has always been rejected, since we don't want to risk reducing performance in the Firefox PDF viewer simply because some users of the general PDF.js library are *incorrectly* extending the `Array.prototype` with enumerable properties. With this patch the general PDF.js library will now fail immediately with a hopefully useful Error message, rather than having (some) fonts fail to render, when the `Array.prototype` is incorrectly extended. Note that I did consider making this a warning, but ultimately decided against it since it's first of all possible to disable those (with the `verbosity` parameter). Secondly, even when printed, warnings can be easy to overlook and finally a warning may also *seem* OK to ignore (as opposed to an actual Error). --- src/core/worker.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/core/worker.js b/src/core/worker.js index 74c5fc566..0b03785ba 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -117,6 +117,26 @@ var WorkerMessageHandler = { ); } + if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { + // Fail early, and predictably, rather than having (some) fonts fail to + // load/render with slightly cryptic error messages in environments where + // the `Array.prototype` has been *incorrectly* extended. + // + // PLEASE NOTE: We do *not* want to slow down font parsing by adding + // `hasOwnProperty` checks all over the code-base. + const enumerableProperties = []; + for (const property in []) { + enumerableProperties.push(property); + } + if (enumerableProperties.length) { + throw new Error( + "The `Array.prototype` contains unexpected enumerable properties: " + + enumerableProperties.join(", ") + + "; thus breaking e.g. `for...in` iteration of `Array`s." + ); + } + } + var docId = docParams.docId; var docBaseUrl = docParams.docBaseUrl; var workerHandlerName = docParams.docId + "_worker";