Skip to content

pdfiumload: guard against NULL-bitmaps #4599

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

Merged
merged 2 commits into from
Jul 7, 2025
Merged

Conversation

zhifengzhuang
Copy link
Contributor

@zhifengzhuang zhifengzhuang commented Jul 4, 2025

  • Fix pdfiumload.c vips_foreign_load_pdf_generate(). Inconsistent PDF page dimensions (varying width/height) may generate empty Bitmaps, leading to crashes in PDFium versions prior to 6633.
  • We could reproduce using the pdf
    052201055248624de6f3063354544793.pdf
    : vips pdfload 052201055248624de6f3063354544793.pdf out.jpeg --n=-1 --dpi=180
image
  • Draw a background color on outRegion to maintain consistency with Poppler's rendering behavior.

@kleisauke
Copy link
Member

  • Fix pdfiumload.c vips_foreign_load_pdf_generate(). Inconsistent PDF page dimensions (varying width/height) may generate empty Bitmaps, leading to crashes in PDFium versions prior to 6633.

I wonder if commit 2fdab9b is also related here.

  • Draw a background color on outRegion to maintain consistency with Poppler's rendering behavior.

This effectively reverts commit 985fb1d, I'm not sure if that's wanted.

@zhifengzhuang
Copy link
Contributor Author

Commit 2fdab9b seems not to related here. Older pdfium(<6633) will crash when an empty bitmap pass to FPDF_FFLDraw. We should check the rect width&height before we call FPDF_FFLDraw?
Commit 985fb1d seems to related here. When there is no overlapping area between the VipsRegion and the PDF, actively draw the background color to ensure the PDFium output matches that of Poppler.

@jcupitt
Copy link
Member

jcupitt commented Jul 5, 2025

Hi @zhifengzhuang, thank you for this PR!

I wonder if commit 2fdab9b is also related here.

I think that's unrelated -- this PR fixes the case where you have a narrow page and the tilecache asks for a rect outside the page boundary.

poppler deals with this gracefully, but (as @zhifengzhuang says) older pdfiums will crash.

This effectively reverts commit 985fb1d, I'm not sure if that's wanted.

I agree, I'm not sure about the change to background. I think this is a case where PDFium has better transparency support than poppler, so we don't want to match the behaviour exactly.

/*
* Same with popperload
*/
vips_region_paint_pel(out_region, r, pdf->ink);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should do this. We set the background when required with FPDFBitmap_FillRect() below.

Copy link
Contributor Author

@zhifengzhuang zhifengzhuang Jul 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should do this. We set the background when required with FPDFBitmap_FillRect() below.

So maybe we could paint background color to out_region when rect is empty?

@@ -592,39 +597,43 @@ vips_foreign_load_pdf_generate(VipsRegion *out_region,
if (vips_foreign_load_pdf_get_page(pdf, pdf->page_no + i))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could move inside the rect size test if(), eg.:

    top = r->top;
    while (top < VIPS_RECT_BOTTOM(r)) {
        FPDF_BITMAP bitmap; 

        /* Is the rect within this page? It might not be if the output is more
         * than one tile wide and this page is narrower.
         */
        VipsRect rect;
        vips_rect_intersectrect(r, &pdf->pages[i], &rect);
        if (rect.width > 0 && 
            rect.height > 0) {

            if (vips_foreign_load_pdf_get_page(pdf, pdf->page_no + i))
                return -1;

            vips__worker_lock(&vips_pdfium_mutex);

            /* 4 means RGBA.
             */ 
            bitmap = FPDFBitmap_CreateEx(rect.width, rect.height, 4,
                VIPS_REGION_ADDR(out_region, rect.left, rect.top),
                VIPS_REGION_LSKIP(out_region));
... etc

@kleisauke
Copy link
Member

kleisauke commented Jul 6, 2025

I can confirm that this issue reproduces with PDFium 6611 but does not occur with PDFium 6666. Tested using:

Details
# export PDFIUM_VERSION=6666
export PDFIUM_VERSION=6611
mkdir -p $HOME/pdfium-linux-x64/lib/pkgconfig
curl -Ls https://github.com/bblanchon/pdfium-binaries/releases/download/chromium%2F$PDFIUM_VERSION/pdfium-linux-x64.tgz | tar xzC $HOME/pdfium-linux-x64
cat > $HOME/pdfium-linux-x64/lib/pkgconfig/pdfium.pc << EOF
prefix=$HOME/pdfium-linux-x64
exec_prefix=\${prefix}
libdir=\${exec_prefix}/lib
includedir=\${prefix}/include

Name: pdfium
Description: PDFium
Version: $PDFIUM_VERSION
Libs: -L\${libdir} -lpdfium
Cflags: -I\${includedir}
EOF

export PKG_CONFIG_PATH=$HOME/pdfium-linux-x64/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}
export LD_LIBRARY_PATH=$HOME/pdfium-linux-x64/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
pkg-config --exists --print-errors "pdfium >= 4200" && echo OK

meson setup build --prefix=/usr -Ddeprecated=false -Dexamples=false -Dintrospection=disabled
meson compile -Cbuild
sudo meson install -Cbuild

It looks like this was fixed with commit https://pdfium.googlesource.com/pdfium/+/f8e68068d9301f24993afd94c270860dc0244674, i.e. this diff:

@@ -696,8 +727,13 @@ FPDF_EXPORT void FPDF_CALLCONV FPDF_FFLDraw(FPDF_FORMHANDLE hHandle,
                                             int size_y,
                                             int rotate,
                                             int flags) {
-  FFLCommon(hHandle, bitmap, nullptr, page, start_x, start_y, size_x, size_y,
-            rotate, flags);
+  CFX_DIBitmap* cbitmap = CFXDIBitmapFromFPDFBitmap(bitmap);
+  if (!cbitmap) {
+    return;
+  }
+
+  FFLCommon(hHandle, page, cbitmap, start_x, start_y, size_x, size_y, rotate,
+            flags);
 }
 
 #if defined(PDF_USE_SKIA)

Which ensures NULL bitmaps are handled gracefully in FPDF_FFLDraw().

@zhifengzhuang zhifengzhuang force-pushed the master branch 2 times, most recently from 7f8f74d to 13eef6f Compare July 7, 2025 04:04
@zhifengzhuang
Copy link
Contributor Author

zhifengzhuang commented Jul 7, 2025

Thanks for replying. I remove vips_region_paint_pel and update test if().

@zhifengzhuang
Copy link
Contributor Author

zhifengzhuang commented Jul 7, 2025

I can confirm that this issue reproduces with PDFium 6611 but does not occur with PDFium 6666. Tested using:

Details
It looks like this was fixed with commit https://pdfium.googlesource.com/pdfium/+/f8e68068d9301f24993afd94c270860dc0244674, i.e. this diff:

@@ -696,8 +727,13 @@ FPDF_EXPORT void FPDF_CALLCONV FPDF_FFLDraw(FPDF_FORMHANDLE hHandle,
                                             int size_y,
                                             int rotate,
                                             int flags) {
-  FFLCommon(hHandle, bitmap, nullptr, page, start_x, start_y, size_x, size_y,
-            rotate, flags);
+  CFX_DIBitmap* cbitmap = CFXDIBitmapFromFPDFBitmap(bitmap);
+  if (!cbitmap) {
+    return;
+  }
+
+  FFLCommon(hHandle, page, cbitmap, start_x, start_y, size_x, size_y, rotate,
+            flags);
 }
 
 #if defined(PDF_USE_SKIA)

Which ensures NULL bitmaps are handled gracefully in FPDF_FFLDraw().

Yes,it was fixed https://pdfium.googlesource.com/pdfium/+/f8e68068d9301f24993afd94c270860dc0244674 (Just between 6632 & 6633)

@zhifengzhuang zhifengzhuang force-pushed the master branch 2 times, most recently from b45bf87 to 6977e1e Compare July 7, 2025 06:17
@kleisauke kleisauke changed the base branch from master to 8.17 July 7, 2025 09:23
@kleisauke kleisauke changed the title Fix pdfiumload.c vips_foreign_load_pdf_generate() pdfiumload: guard against NULL-bitmaps Jul 7, 2025
@kleisauke
Copy link
Member

I've updated this PR to target the 8.17 branch and revised the commit message and changelog note accordingly.

Co-authored-by: Kleis Auke Wolthuizen <github@kleisauke.nl>
@jcupitt jcupitt merged commit 122e572 into libvips:8.17 Jul 7, 2025
6 checks passed
@jcupitt
Copy link
Member

jcupitt commented Jul 7, 2025

Great! Let's merge!

Thank you for doing this work, @zhifengzhuang, this is a good thing to fix. This change will be in libvips 8.17.1.

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

Successfully merging this pull request may close these issues.

3 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy