diff --git a/fuzz/decompress.c b/fuzz/decompress.c index a84cdac9..48eb3126 100644 --- a/fuzz/decompress.c +++ b/fuzz/decompress.c @@ -38,13 +38,19 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { tjhandle handle = NULL; unsigned char *dstBuf = NULL; - int width, height, jpegSubsamp, jpegColorspace, pfi; + int width = 0, height = 0, jpegSubsamp, jpegColorspace, pfi; /* TJPF_RGB-TJPF_BGR share the same code paths, as do TJPF_RGBX-TJPF_XRGB and TJPF_RGBA-TJPF_ARGB. Thus, the pixel formats below should be the minimum necessary to achieve full coverage. */ enum TJPF pixelFormats[NUMPF] = { TJPF_RGB, TJPF_BGRX, TJPF_GRAY, TJPF_CMYK }; +#if defined(__has_feature) && __has_feature(memory_sanitizer) + /* The libjpeg-turbo SIMD extensions produce false positives with + MemorySanitizer. */ + putenv("JSIMD_FORCENONE=1"); +#endif + if ((handle = tjInitDecompress()) == NULL) goto bailout; @@ -75,12 +81,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) if ((dstBuf = (unsigned char *)malloc(w * h * tjPixelSize[pf])) == NULL) goto bailout; - tjDecompress2(handle, data, size, dstBuf, w, 0, h, pf, flags); - - /* Touch all of the output pixels in order to catch uninitialized reads - when using MemorySanitizer. */ - for (i = 0; i < w * h * tjPixelSize[pf]; i++) - sum += dstBuf[i]; + if (tjDecompress2(handle, data, size, dstBuf, w, 0, h, pf, flags) == 0) { + /* Touch all of the output pixels in order to catch uninitialized reads + when using MemorySanitizer. */ + for (i = 0; i < w * h * tjPixelSize[pf]; i++) + sum += dstBuf[i]; + } free(dstBuf); dstBuf = NULL; diff --git a/fuzz/decompress_yuv.c b/fuzz/decompress_yuv.c index 3fc1b898..ea9c6b85 100644 --- a/fuzz/decompress_yuv.c +++ b/fuzz/decompress_yuv.c @@ -38,13 +38,19 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { tjhandle handle = NULL; unsigned char *dstBuf = NULL, *yuvBuf = NULL; - int width, height, jpegSubsamp, jpegColorspace, pfi; + int width = 0, height = 0, jpegSubsamp, jpegColorspace, pfi; /* TJPF_RGB-TJPF_BGR share the same code paths, as do TJPF_RGBX-TJPF_XRGB and TJPF_RGBA-TJPF_ARGB. Thus, the pixel formats below should be the minimum necessary to achieve full coverage. */ enum TJPF pixelFormats[NUMPF] = { TJPF_BGR, TJPF_XRGB, TJPF_GRAY }; +#if defined(__has_feature) && __has_feature(memory_sanitizer) + /* The libjpeg-turbo SIMD extensions produce false positives with + MemorySanitizer. */ + putenv("JSIMD_FORCENONE=1"); +#endif + if ((handle = tjInitDecompress()) == NULL) goto bailout; @@ -75,13 +81,14 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) (unsigned char *)malloc(tjBufSizeYUV2(w, 1, h, jpegSubsamp))) == NULL) goto bailout; - tjDecompressToYUV2(handle, data, size, yuvBuf, w, 1, h, flags); - tjDecodeYUV(handle, yuvBuf, 1, jpegSubsamp, dstBuf, w, 0, h, pf, flags); - - /* Touch all of the output pixels in order to catch uninitialized reads - when using MemorySanitizer. */ - for (i = 0; i < w * h * tjPixelSize[pf]; i++) - sum += dstBuf[i]; + if (tjDecompressToYUV2(handle, data, size, yuvBuf, w, 1, h, flags) == 0 && + tjDecodeYUV(handle, yuvBuf, 1, jpegSubsamp, dstBuf, w, 0, h, pf, + flags) == 0) { + /* Touch all of the output pixels in order to catch uninitialized reads + when using MemorySanitizer. */ + for (i = 0; i < w * h * tjPixelSize[pf]; i++) + sum += dstBuf[i]; + } free(dstBuf); dstBuf = NULL; diff --git a/fuzz/transform.c b/fuzz/transform.c index aa4673f7..2890a40f 100644 --- a/fuzz/transform.c +++ b/fuzz/transform.c @@ -40,9 +40,15 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) tjhandle handle = NULL; unsigned char *dstBufs[NUMXFORMS] = { NULL, NULL, NULL }; unsigned long dstSizes[NUMXFORMS] = { 0, 0, 0 }, maxBufSize; - int width, height, jpegSubsamp, jpegColorspace, i, t; + int width = 0, height = 0, jpegSubsamp, jpegColorspace, i, t; tjtransform transforms[NUMXFORMS]; +#if defined(__has_feature) && __has_feature(memory_sanitizer) + /* The libjpeg-turbo SIMD extensions produce false positives with + MemorySanitizer. */ + putenv("JSIMD_FORCENONE=1"); +#endif + if ((handle = tjInitTransform()) == NULL) goto bailout; @@ -73,14 +79,22 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) transforms[1].r.h = (height + 1) / 2; transforms[1].op = TJXOP_TRANSPOSE; transforms[1].options = TJXOPT_GRAY | TJXOPT_CROP | TJXOPT_COPYNONE; +#if defined(__has_feature) && __has_feature(memory_sanitizer) + /* The libjpeg-turbo baseline Huffman encoder produces false positives with + MemorySanitizer. */ + transforms[1].options |= TJXOPT_PROGRESSIVE; +#endif dstBufs[1] = (unsigned char *)malloc(tjBufSize((width + 1) / 2, (height + 1) / 2, - jpegSubsamp)); + TJSAMP_GRAY)); if (!dstBufs[1]) goto bailout; transforms[2].op = TJXOP_ROT90; transforms[2].options = TJXOPT_TRIM | TJXOPT_COPYNONE; +#if defined(__has_feature) && __has_feature(memory_sanitizer) + transforms[2].options |= TJXOPT_PROGRESSIVE; +#endif dstBufs[2] = (unsigned char *)malloc(tjBufSize(height, width, jpegSubsamp)); if (!dstBufs[2]) goto bailout;