Avoid tautological comparisons

Several TurboJPEG functions store their return value in an unsigned
long long intermediate and compare it against the maximum value of
unsigned long or size_t in order to avoid integer overflow.  However,
such comparisons are tautological (always true, i.e. redundant) unless
the size of unsigned long or size_t is less than the size of unsigned
long long.  Explicitly guarding the comparisons with #if avoids compiler
warnings with -Wtautological-constant-in-range-compare in Clang and also
makes it clear to the reader that the comparisons are only intended for
32-bit code.

Refer to #752
This commit is contained in:
DRC
2024-03-08 10:29:27 -05:00
parent 34c055851e
commit 905ec0fa01
4 changed files with 29 additions and 2 deletions

View File

@@ -37,6 +37,9 @@
#include <math.h> #include <math.h>
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#if !defined(_MSC_VER) || _MSC_VER > 1600
#include <stdint.h>
#endif
#include <cdjpeg.h> #include <cdjpeg.h>
#include "./tjutil.h" #include "./tjutil.h"
#include "./turbojpeg.h" #include "./turbojpeg.h"
@@ -223,9 +226,11 @@ static int decomp(unsigned char **jpegBufs, size_t *jpegSizes, void *dstBuf,
pitch = scaledw * ps; pitch = scaledw * ps;
if (dstBuf == NULL) { if (dstBuf == NULL) {
#if ULLONG_MAX > SIZE_MAX
if ((unsigned long long)pitch * (unsigned long long)scaledh * if ((unsigned long long)pitch * (unsigned long long)scaledh *
(unsigned long long)sampleSize > (unsigned long long)((size_t)-1)) (unsigned long long)sampleSize > (unsigned long long)((size_t)-1))
THROW("allocating destination buffer", "Image is too large"); THROW("allocating destination buffer", "Image is too large");
#endif
if ((dstBuf = malloc((size_t)pitch * scaledh * sampleSize)) == NULL) if ((dstBuf = malloc((size_t)pitch * scaledh * sampleSize)) == NULL)
THROW_UNIX("allocating destination buffer"); THROW_UNIX("allocating destination buffer");
dstBufAlloc = 1; dstBufAlloc = 1;
@@ -382,9 +387,11 @@ static int fullTest(tjhandle handle, void *srcBuf, int w, int h, int subsamp,
int ntilesw = 1, ntilesh = 1, pitch = w * ps; int ntilesw = 1, ntilesh = 1, pitch = w * ps;
const char *pfStr = pixFormatStr[pf]; const char *pfStr = pixFormatStr[pf];
#if ULLONG_MAX > SIZE_MAX
if ((unsigned long long)pitch * (unsigned long long)h * if ((unsigned long long)pitch * (unsigned long long)h *
(unsigned long long)sampleSize > (unsigned long long)((size_t)-1)) (unsigned long long)sampleSize > (unsigned long long)((size_t)-1))
THROW("allocating temporary image buffer", "Image is too large"); THROW("allocating temporary image buffer", "Image is too large");
#endif
if ((tmpBuf = malloc((size_t)pitch * h * sampleSize)) == NULL) if ((tmpBuf = malloc((size_t)pitch * h * sampleSize)) == NULL)
THROW_UNIX("allocating temporary image buffer"); THROW_UNIX("allocating temporary image buffer");

View File

@@ -40,6 +40,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <limits.h>
#if !defined(_MSC_VER) || _MSC_VER > 1600
#include <stdint.h>
#endif
#include <turbojpeg.h> #include <turbojpeg.h>
@@ -335,9 +339,11 @@ int main(int argc, char **argv)
outSubsamp = inSubsamp; outSubsamp = inSubsamp;
pixelFormat = TJPF_BGRX; pixelFormat = TJPF_BGRX;
#if ULLONG_MAX > SIZE_MAX
if ((unsigned long long)width * height * tjPixelSize[pixelFormat] > if ((unsigned long long)width * height * tjPixelSize[pixelFormat] >
(unsigned long long)((size_t)-1)) (unsigned long long)((size_t)-1))
THROW("allocating uncompressed image buffer", "Image is too large"); THROW("allocating uncompressed image buffer", "Image is too large");
#endif
if ((imgBuf = if ((imgBuf =
(unsigned char *)malloc(sizeof(unsigned char) * width * height * (unsigned char *)malloc(sizeof(unsigned char) * width * height *
tjPixelSize[pixelFormat])) == NULL) tjPixelSize[pixelFormat])) == NULL)

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C)2009-2023 D. R. Commander. All Rights Reserved. * Copyright (C)2009-2024 D. R. Commander. All Rights Reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@@ -366,8 +366,11 @@ DLLEXPORT _JSAMPLE *GET_NAME(tj3LoadImage, BITS_IN_JSAMPLE)
*pixelFormat = cs2pf[cinfo->in_color_space]; *pixelFormat = cs2pf[cinfo->in_color_space];
pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); pitch = PAD((*width) * tjPixelSize[*pixelFormat], align);
if ((unsigned long long)pitch * (unsigned long long)(*height) > if (
#if ULLONG_MAX > SIZE_MAX
(unsigned long long)pitch * (unsigned long long)(*height) >
(unsigned long long)((size_t)-1) || (unsigned long long)((size_t)-1) ||
#endif
(dstBuf = (_JSAMPLE *)malloc(pitch * (*height) * (dstBuf = (_JSAMPLE *)malloc(pitch * (*height) *
sizeof(_JSAMPLE))) == NULL) sizeof(_JSAMPLE))) == NULL)
THROW("Memory allocation failure"); THROW("Memory allocation failure");

View File

@@ -32,6 +32,9 @@
#include <ctype.h> #include <ctype.h>
#include <limits.h> #include <limits.h>
#if !defined(_MSC_VER) || _MSC_VER > 1600
#include <stdint.h>
#endif
#include <jinclude.h> #include <jinclude.h>
#define JPEG_INTERNALS #define JPEG_INTERNALS
#include <jpeglib.h> #include <jpeglib.h>
@@ -946,8 +949,10 @@ DLLEXPORT size_t tj3JPEGBufSize(int width, int height, int jpegSubsamp)
mcuh = tjMCUHeight[jpegSubsamp]; mcuh = tjMCUHeight[jpegSubsamp];
chromasf = jpegSubsamp == TJSAMP_GRAY ? 0 : 4 * 64 / (mcuw * mcuh); chromasf = jpegSubsamp == TJSAMP_GRAY ? 0 : 4 * 64 / (mcuw * mcuh);
retval = PAD(width, mcuw) * PAD(height, mcuh) * (2ULL + chromasf) + 2048ULL; retval = PAD(width, mcuw) * PAD(height, mcuh) * (2ULL + chromasf) + 2048ULL;
#if ULLONG_MAX > ULONG_MAX
if (retval > (unsigned long long)((unsigned long)-1)) if (retval > (unsigned long long)((unsigned long)-1))
THROWG("Image is too large", 0); THROWG("Image is too large", 0);
#endif
bailout: bailout:
return (size_t)retval; return (size_t)retval;
@@ -981,8 +986,10 @@ DLLEXPORT unsigned long TJBUFSIZE(int width, int height)
larger than the uncompressed input (we wouldn't mention it if it hadn't larger than the uncompressed input (we wouldn't mention it if it hadn't
happened before.) */ happened before.) */
retval = PAD(width, 16) * PAD(height, 16) * 6ULL + 2048ULL; retval = PAD(width, 16) * PAD(height, 16) * 6ULL + 2048ULL;
#if ULLONG_MAX > ULONG_MAX
if (retval > (unsigned long long)((unsigned long)-1)) if (retval > (unsigned long long)((unsigned long)-1))
THROWG("Image is too large", (unsigned long)-1); THROWG("Image is too large", (unsigned long)-1);
#endif
bailout: bailout:
return (unsigned long)retval; return (unsigned long)retval;
@@ -1008,8 +1015,10 @@ DLLEXPORT size_t tj3YUVBufSize(int width, int align, int height, int subsamp)
if (pw == 0 || ph == 0) return 0; if (pw == 0 || ph == 0) return 0;
else retval += (unsigned long long)stride * ph; else retval += (unsigned long long)stride * ph;
} }
#if ULLONG_MAX > ULONG_MAX
if (retval > (unsigned long long)((unsigned long)-1)) if (retval > (unsigned long long)((unsigned long)-1))
THROWG("Image is too large", 0); THROWG("Image is too large", 0);
#endif
bailout: bailout:
return (size_t)retval; return (size_t)retval;
@@ -1123,8 +1132,10 @@ DLLEXPORT size_t tj3YUVPlaneSize(int componentID, int width, int stride,
else stride = abs(stride); else stride = abs(stride);
retval = (unsigned long long)stride * (ph - 1) + pw; retval = (unsigned long long)stride * (ph - 1) + pw;
#if ULLONG_MAX > ULONG_MAX
if (retval > (unsigned long long)((unsigned long)-1)) if (retval > (unsigned long long)((unsigned long)-1))
THROWG("Image is too large", 0); THROWG("Image is too large", 0);
#endif
bailout: bailout:
return (size_t)retval; return (size_t)retval;