Fix Form XObject with extreme BBox values causing blank white page in Chromium#20876
Fix Form XObject with extreme BBox values causing blank white page in Chromium#20876pengkunbin wants to merge 1 commit intomozilla:masterfrom
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #20876 +/- ##
==========================================
+ Coverage 62.58% 62.60% +0.02%
==========================================
Files 173 173
Lines 121275 121297 +22
==========================================
+ Hits 75894 75936 +42
+ Misses 45381 45361 -20
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…flow When a Form XObject has extreme BBox values (e.g. very large coordinates), Skia's Float32 arithmetic can overflow causing a blank white page in Chromium-based browsers. Fix by clamping the BBox to the canvas bounds in device space before building the clip path, and use the clamped bounds array indices when calling recordClipBox. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dfd1cab to
f772d90
Compare
|
Have you actually written this yourself, or is it completely AI generated? |
My goal was to solve the white screen issue that my users encountered when using the PDF viewer. I used AI to quickly familiarize myself with the rendering pipeline and traced the root cause to a Skia rendering boundary issue. I now fully understand the entire rendering flow. This was accomplished collaboratively with AI. |
There are several problems with this patch:
So more generally, please file bugs with useful test cases. If you've any ideas on how the problem can be fixed, please propose them in the bug itself and we can chat with you. |
|
I think I've made myself quite clear:
If this is how you treat contributors, I wish you the best of luck continuing to maintain pdf.js. |
|
I've been wrong: the pdf contains some data but none of the viewers I tested were able to render it (Chrome, Firefox, Preview, Acrobat, Foxit) and I, too quickly, looked at the pdf let me think that it was just a white image. |
I maintain a PDF viewer built on pdf.js with over a million daily active users. These unusual PDFs were reported to me by real users. I respect every single one of my users. When they encounter issues reading a PDF, I always look for the cause in the code. Telling them "your PDF is broken" — don't you think that's a bit too arrogant? From a behavioral standpoint, the canvas receives invalid data before rendering, which causes the entire render to fail. Yet other layers (e.g. the text layer) render just fine. This inconsistency is confusing and feels like a bug. This change simply adds data validation to ensure rendering stays within canvas's capability bounds. If you feel the performance aspect needs optimization, I'm happy to discuss or you're welcome to modify my code directly. Anyway, I'm here to make pdf.js better. |
Over the years, we spent a lot of time to fix some issues because of broken PDFs. I don't see any problem to tell you that the pdf is broken when as a matter of fact, the pdf is broken. And sometimes, as explained in my previous comment, it's a better idea to try to fix the root cause of the problem (i.e. fix the producer instead of fixing the reader). Anyway, I don't want to have whatever argument with you or any people, I've more interesting to do. And to speak about code, I'm not opposed to figure out a solution, I'd really prefer avoiding to do that when drawing. |
|
OK Here's my rationale:
If you think this code change is too heavy, I can modify it to: What do you think? Looking forward to your guidance. @calixteman |
|
Cut to the chase @calixteman |
Fixes #20872.
Problem
Some PDFs contain Form XObjects with astronomically large BBox values (e.g. ±8.988e76), intended to express "no clipping / cover the entire page".
paintFormXObjectBeginpassed these raw coordinates directly toPath2D.rect():e.g.
<< /Filter /FlateDecode /Type /XObject /Subtype /Form /FormType 1 /BBox [-89884656743115785407263711865852178399035283762922498299458738401578630390014269380294779316383439085770229476757191232117160663444732091384233773351768758493024955288275641038122745045194664472037934254227566971152291618451611474082904279666061674137398913102072361584369088590459649940625202013092062429184 -89884656743115785407263711865852178399035283762922498299458738401578630390014269380294779316383439085770229476757191232117160663444732091384233773351768758493024955288275641038122745045194664472037934254227566971152291618451611474082904279666061674137398913102072361584369088590459649940625202013092062429184 89884656743115785407263711865852178399035283762922498299458738401578630390014269380294779316383439085770229476757191232117160663444732091384233773351768758493024955288275641038122745045194664472037934254227566971152291618451611474082904279666061674137398913102072361584369088590459649940625202013092062429184 89884656743115785407263711865852178399035283762922498299458738401578630390014269380294779316383439085770229476757191232117160663444732091384233773351768758493024955288275641038122745045194664472037934254227566971152291618451611474082904279666061674137398913102072361584369088590459649940625202013092062429184]
Chromium/Skia processes
Path2Dcoordinates as Float32 internally. Values exceeding Float32.MAX (∼3.4e38) overflow to ±Infinity, silently invalidating the clip path and clearing the entire canvas, resulting in a blank white page.Fix
Mirror the approach already used in
beginGroup: transform the bbox to canvas (device) space viaUtil.axialAlignedBoundingBox, then clamp to the actual canvas bounds withUtil.intersect(bounds, canvasBounds). For extreme BBox values this produces a clip rect equal to the full canvas, semantically equivalent and numerically safe.Before / After
Before:

After:

File:
issue20872.pdf
the commits have been squashed into a single one @Snuffleupagus