Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple PDF with standard Courier font won't load in pdf.js version 2.3.200 running in Chrome version 92 #13771

Closed
mullery opened this issue Jul 21, 2021 · 10 comments

Comments

@mullery
Copy link

mullery commented Jul 21, 2021

Attach (recommended) or Link to PDF file here:

Configuration:

  • Web browser and its version: Chrome 92
  • Operating system and its version: Windows 10
  • PDF.js version: 2.3.200
  • Is a browser extension: No

Steps to reproduce the problem:

  1. Load the attached 1-page PDF in pdf.js 2.3.200 using Chrome 92

What is the expected behavior?

The PDF should load properly. It loaded fine in all previous versions of Chrome, but will not load in Chrome version 92.

What went wrong?

The PDF fails to load properly. The text layer appears to be created, but the canvas is not generated properly. The PDF appears to be blank on the screen.

The following warning appears in the Chrome console:

Warning: getOperatorList - ignoring errors during "GetOperatorList: page 0" task: "DataCloneError: Failed to execute 'postMessage' on 'DedicatedWorkerGlobalScope': function at() { [native code] } could not be cloned.".

This appears to have something to do with the source PDF using the standard Courier font (not an embedded font). I have generated newer PDFs using an embedded font and they load properly in pdf.js 2.3.200 in Chrome 92. I debugged the pdf.js code and it does appear to be throwing an exception in the font loading code. I tried loading the same test PDF into some newer versions of pdf.js and it does appear to load in 2.5.207 and newer when running in Chrome 92. There is something about the combination of the 2.3.200 version of pdf.js, Chrome 92, and the font situation that is resulting in the issue.

Upgrading to a newer version of pdf.js is not a short-term solution for us because we still have a few users running IE11. I am hoping someone can help shed some light on the issue and perhaps point to the change that was made in Chrome 92 that is causing this issue. If it is a Chrome bug, I can report it to Google or maybe there is a Chrome flag that can be adjusted to correct the issue?

Thanks!

test.pdf

@Snuffleupagus
Copy link
Collaborator

PDF.js version: 2.3.200

Unfortunately that version is way too old to be supported (note that it's released in 2019); please find the latest releases at https://mozilla.github.io/pdf.js/getting_started/#download

The PDF should load properly. It loaded fine in all previous versions of Chrome, but will not load in Chrome version 92.

That'd suggest, rather clearly in my opinion, that it's a regression in the browser rather than in the PDF.js library if the only thing being updated here is the browser itself.
(It ought to be possible to bisect Google Chrome to figure when/where the bug originated, however since I've never had to bisect Chromium I wouldn't be able to tell you where to start unfortunately.)

Upgrading to a newer version of pdf.js is not a short-term solution for us because we still have a few users running IE11.

For your information: Please keep in mind that IE11 is now explicitly unsupported in the PDF.js project, see https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support

@mullery
Copy link
Author

mullery commented Jul 22, 2021

Thanks for your response. We are looking to drop IE11 support for our existing users within the next few months. At that time we will certainly be moving to the latest version of pdf.js. Until that time we're going to have to provide some guidance for users who are impacted by this issue. I suspect Edge Chromium will experience the same problem when version 92 ships this month, so ironically we may have to ask our users to specifically use IE11 to work around the issue in the short-term.

I agree that this could very well be a Chrome/Chromium regression bug, but it is very difficult to pinpoint the exact spot in the pdf.js source code where the issue is occurring and then correlate that to a browser behavior. I'm going to continue down that path and hopefully find the precise issue with font loading that is tripping up Chrome 92. That may lead me to reporting an issue with Chrome if I can localize it.

Thanks again!

@Snuffleupagus
Copy link
Collaborator

Closing for now, since as-is this doesn't clearly point to a bug in the PDF.js library (but rather the browser) and the (unpaid) PDF.js contributors cannot realistically help with such an "ancient" version of the library unfortunately.

@K1rdro
Copy link

K1rdro commented Jul 23, 2021

I'm running into this issue with the Chrome extension:
pdf.worker.js:1710 Warning: getOperatorList - ignoring errors during "GetOperatorList: page 0" task: "DataCloneError: Failed to execute 'postMessage' on 'DedicatedWorkerGlobalScope': function at() { [native code] } could not be cloned.".

Tested on Chrome 92 & 94 (canary)

@mullery
Copy link
Author

mullery commented Jul 23, 2021

We isolated the issue and confirmed it is a defect in pdf.js that was fixed in v2.5. All earlier versions of pdf.js will encounter the problem when opening a PDF containing the standard Courier font (not an embedded font) on Chrome 92.

The problem is in fonts.js. Prior to version 2.5, The exportData() function would copy all font properties to a data object prior to a postMessage call to send the data to another thread. In Chrome 92, the widths property of the font object contains a mysterious at() function. Functions cannot be cloned and passed via postMessage. There is a TODO comment in the older exportData() function that reads:

// TODO remove enumerating of the properties, e.g. hardcode exact names.

The exportData() function was refactored in 2.5, with the refactored code preventing the issue in Chrome 92.

Here's the commit that fixes the issue:

664f7de

We were forced to create a custom build of pdf.js v2.3.200 where we applied the same fix in order to resolve the issue and maintain IE11 compatibility until we are able to deprecate IE11 support for all of our users.

I hope this helps.

@ajinkyapisal
Copy link

ajinkyapisal commented Jul 29, 2021

The problem is in fonts.js. Prior to version 2.5, The exportData() function would copy all font properties to a data object prior to a postMessage call to send the data to another thread. In Chrome 92, the widths property of the font object contains a mysterious at() function.

@mullery We ran into the same issue. The issue is not in the exportData method but the method that sets the Font widths property. We are on very old version (1.7.297) of the pdf.js but it looks like the problematic code is still the same. The following code is from the method buildCharCodeToWidth of the pdf.worker.js.

if (charCode in encoding && widthsByGlyphName[encoding[charCode]]) {
  widths[charCode] = widthsByGlyphName[encoding[charCode]];
  continue;
}

For courier font, encoding[64] contains a string value "at" and widthsByGlyphName is an empty array. Now, ideally widthsByGlyphName['at'] should return undefined but with Chrome 92 now it returns ƒ at() { [native code] }

This is happening because in the Chrome 92, Array now has a new experimental method called at.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at

So when you access array using string index, it will look for the index in the string keys and that includes all methods too. This is why when you do widthsByGlyphName['at'] it returns at() method instead of undefined.

To fix this issue, we are now using Array.find(). This is not a good performance wise but this temporarily fixes our issue.

image

Note: It looks like the same code is present in the latest version of the pdf.js too. I will do some testing and create a PR for this fix.

@Snuffleupagus
Copy link
Collaborator

We are on very old version (1.7.297) of the pdf.js but it looks like the problematic code is still the same.
[...]
So when you access array using string index, it will look for the index in the string keys and that includes all methods too. This is why when you do widthsByGlyphName['at'] it returns at() method instead of undefined.

Please note that it's really not advised to use such an "ancient" version of the library; please find the latest releases at https://mozilla.github.io/pdf.js/getting_started/#download

Furthermore, with the changes made in PR #12924 this should no longer happen since widthsByGlyphName is now an Object rather than an Array.

To fix this issue, we are now using Array.find()
[...]
I will do some testing and create a PR for this fix.

As explained above, this has already been fixed and we won't accept a patch which adds unnecessary overhead here.

@ajinkyapisal
Copy link

As explained above, this has already been fixed and we won't accept a patch which adds unnecessary overhead here.

Yeah, that makes sense. Thanks for pointing me in the right direction.

Please note that it's really not advised to use such an "ancient" version of the library; please find the latest releases at https://mozilla.github.io/pdf.js/getting_started/#download

Yeah. That's the plan.

@K1rdro
Copy link

K1rdro commented Jul 29, 2021

Since I'm still having this problem with the Chrome plugin, should I open a new issue?

@Rob--W
Copy link
Member

Rob--W commented Aug 1, 2021

Please don't open a new issue unless the issue also reproduces in the latest version, i.e. the demo at https://mozilla.github.io/pdf.js/web/viewer.html . I'm working on an update in #13669.

sergeev-ms added a commit to sergeev-ms/wt-vaadin-pdf.js that referenced this issue Aug 28, 2021
sergeev-ms added a commit to sergeev-ms/pdf-viewer that referenced this issue Aug 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants