TurboJPEG: Properly handle gigapixel images
Prevent several integer overflow issues and subsequent segfaults that occurred when attempting to compress or decompress gigapixel images with the TurboJPEG API: - Modify tjBufSize(), tjBufSizeYUV2(), and tjPlaneSizeYUV() to avoid integer overflow when computing the return values and to return an error if such an overflow is unavoidable. - Modify tjunittest to validate the above. - Modify tjCompress2(), tjEncodeYUVPlanes(), tjDecompress2(), and tjDecodeYUVPlanes() to avoid integer overflow when computing the row pointers in the 64-bit TurboJPEG C API. - Modify TJBench (both C and Java versions) to avoid overflowing the size argument to malloc()/new and to fail gracefully if such an overflow is unavoidable. In general, this allows gigapixel images to be accommodated by the 64-bit TurboJPEG C API when using automatic JPEG buffer (re)allocation. Such images cannot currently be accommodated without automatic JPEG buffer (re)allocation, due to the fact that tjAlloc() accepts a 32-bit integer argument (oops.) Such images cannot be accommodated in the TurboJPEG Java API due to the fact that Java always uses a signed 32-bit integer as an array index. Fixes #361
This commit is contained in:
@@ -121,6 +121,8 @@ final class TJBench {
|
||||
int rindex = TJ.getRedOffset(pixelFormat);
|
||||
int gindex = TJ.getGreenOffset(pixelFormat);
|
||||
int bindex = TJ.getBlueOffset(pixelFormat);
|
||||
if ((long)w[0] * (long)h[0] * (long)ps > (long)Integer.MAX_VALUE)
|
||||
throw new Exception("Image is too large");
|
||||
byte[] dstBuf = new byte[w[0] * h[0] * ps];
|
||||
int pixels = w[0] * h[0], dstPtr = 0, rgbPtr = 0;
|
||||
|
||||
@@ -175,8 +177,11 @@ final class TJBench {
|
||||
|
||||
tjd = new TJDecompressor();
|
||||
|
||||
if (dstBuf == null)
|
||||
if (dstBuf == null) {
|
||||
if ((long)pitch * (long)scaledh > (long)Integer.MAX_VALUE)
|
||||
throw new Exception("Image is too large");
|
||||
dstBuf = new byte[pitch * scaledh];
|
||||
}
|
||||
|
||||
/* Set the destination buffer to gray so we know whether the decompressor
|
||||
attempted to write to it */
|
||||
@@ -331,6 +336,8 @@ final class TJBench {
|
||||
String pfStr = PIXFORMATSTR[pf];
|
||||
YUVImage yuvImage = null;
|
||||
|
||||
if ((long)pitch * (long)h > (long)Integer.MAX_VALUE)
|
||||
throw new Exception("Image is too large");
|
||||
tmpBuf = new byte[pitch * h];
|
||||
|
||||
if (quiet == 0)
|
||||
@@ -491,6 +498,8 @@ final class TJBench {
|
||||
int tw, th, ttilew, ttileh, tntilesw, tntilesh, tsubsamp;
|
||||
|
||||
FileInputStream fis = new FileInputStream(fileName);
|
||||
if (fis.getChannel().size() > (long)Integer.MAX_VALUE)
|
||||
throw new Exception("Image is too large");
|
||||
int srcSize = (int)fis.getChannel().size();
|
||||
srcBuf = new byte[srcSize];
|
||||
fis.read(srcBuf, 0, srcSize);
|
||||
|
||||
Reference in New Issue
Block a user