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
Anonymous
Hi,
Thanks for the fix, it is now available in the SVN.
Hervé
Much appreciated, thanks!