Menu

#148 Bugfix for #340 (Calling FreeImage_Paste fails on very large images)

None
pending
None
5
2021-11-04
2021-09-24
No

Hi all

Calling FreeImage_Paste to the bottom right corner of a 32 bit image larger than ~50 000 x 50 000 pixels results in an unsigned overflow/wraparound on the following line:

BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) * FreeImage_GetPitch(dst_dib)) + (x * 4);

A simple cast to size_t for (FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) solves the issue.

Fix attached

Index: CopyPaste.cpp
===================================================================
--- CopyPaste.cpp       (revision 1889)
+++ CopyPaste.cpp       (working copy)
@@ -68,7 +68,7 @@
                return FALSE;
        }

-       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) * FreeImage_GetPitch(dst_dib));
+       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((size_t)(FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) * FreeImage_GetPitch(dst_dib));
        BYTE *src_bits = FreeImage_GetBits(src_dib);

        // combine images
@@ -136,7 +136,7 @@
                }
        }

-       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) *      FreeImage_GetPitch(dst_dib)) + (x >> 1);
+       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((size_t)(FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) *      FreeImage_GetPitch(dst_dib)) + (x >> 1);
        BYTE *src_bits = FreeImage_GetBits(src_dib);

        // combine images
@@ -205,7 +205,7 @@
                return FALSE;
        }

-       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) * FreeImage_GetPitch(dst_dib)) + (x);
+       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((size_t)(FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) * FreeImage_GetPitch(dst_dib)) + (x);
        BYTE *src_bits = FreeImage_GetBits(src_dib);

        if(alpha > 255) {
@@ -247,7 +247,7 @@
                return FALSE;
        }

-       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) * FreeImage_GetPitch(dst_dib)) + (x * 2);
+       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((size_t)(FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) * FreeImage_GetPitch(dst_dib)) + (x * 2);
        BYTE *src_bits = FreeImage_GetBits(src_dib);

        if (alpha > 255) {
@@ -307,7 +307,7 @@
                return FALSE;
        }

-       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) * FreeImage_GetPitch(dst_dib)) + (x * 2);
+       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((size_t)(FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) * FreeImage_GetPitch(dst_dib)) + (x * 2);
        BYTE *src_bits = FreeImage_GetBits(src_dib);

        if (alpha > 255) {
@@ -371,7 +371,7 @@
                return FALSE;
        }

-       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) * FreeImage_GetPitch(dst_dib)) + (x * 3);
+       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((size_t)(FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) * FreeImage_GetPitch(dst_dib)) + (x * 3);
        BYTE *src_bits = FreeImage_GetBits(src_dib);

        if(alpha > 255) {
@@ -413,7 +413,7 @@
                return FALSE;
        }

-       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) * FreeImage_GetPitch(dst_dib)) + (x * 4);
+       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((size_t)(FreeImage_GetHeight(dst_dib) - FreeImage_GetHeight(src_dib) - y) * FreeImage_GetPitch(dst_dib)) + (x * 4);
        BYTE *src_bits = FreeImage_GetBits(src_dib);

        if (alpha > 255) {
@@ -463,7 +463,7 @@
                return FALSE;
        }

-       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((dst_height - src_height - y) * dst_pitch) + (x * (src_line / src_width));
+       BYTE *dst_bits = FreeImage_GetBits(dst_dib) + ((size_t)(dst_height - src_height - y) * dst_pitch) + (x * (src_line / src_width));
        BYTE *src_bits = FreeImage_GetBits(src_dib);

        // combine images
1 Attachments

Discussion

  • Hervé Drolon

    Hervé Drolon - 2021-11-01
    • status: open --> pending
    • assigned_to: Hervé Drolon
    • Group: -->
     
  • Hervé Drolon

    Hervé Drolon - 2021-11-01

    Hi,

    Thanks for the fix, it is now available in the SVN.

    Hervé

     
  • Patrick Pelletier

    Much appreciated, thanks!

     

Anonymous
Anonymous

Add attachments
Cancel