mirror of
https://github.com/libjpeg-turbo/libjpeg-turbo.git
synced 2026-01-18 13:31:21 +01:00
Fuzz: Avoid using temporary files
- When built for fuzzing, expose special versions of tj3LoadImage*() that accept a FILE handle. - Rename cjpeg_main() to cjpeg_fuzzer() and allow a FILE handle to be passed to it as well. - Use fmemopen() to obtain a FILE handle from the fuzzer input data.
This commit is contained in:
@@ -869,6 +869,7 @@ endif()
|
||||
###############################################################################
|
||||
|
||||
if(WITH_FUZZ)
|
||||
add_definitions(-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
|
||||
add_subdirectory(fuzz)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2021, 2024 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2021, 2024, 2026 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -29,13 +29,10 @@
|
||||
/* This fuzz target wraps cjpeg in order to test esoteric compression options
|
||||
as well as the GIF and Targa readers. */
|
||||
|
||||
#define main cjpeg_main
|
||||
#define CJPEG_FUZZER
|
||||
extern "C" {
|
||||
#include "../src/cjpeg.c"
|
||||
}
|
||||
#undef main
|
||||
#undef CJPEG_FUZZER
|
||||
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
@@ -43,40 +40,36 @@ extern "C" {
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
char filename[FILENAME_MAX] = { 0 };
|
||||
char *argv1[] = {
|
||||
(char *)"cjpeg", (char *)"-dct", (char *)"float", (char *)"-memdst",
|
||||
(char *)"-optimize", (char *)"-quality", (char *)"100,99,98",
|
||||
(char *)"-restart", (char *)"2", (char *)"-sample", (char *)"4x1,2x2,1x2",
|
||||
(char *)"-targa", NULL
|
||||
(char *)"-targa"
|
||||
};
|
||||
char *argv2[] = {
|
||||
(char *)"cjpeg", (char *)"-arithmetic", (char *)"-dct", (char *)"float",
|
||||
(char *)"-memdst", (char *)"-quality", (char *)"90,80,70", (char *)"-rgb",
|
||||
(char *)"-sample", (char *)"2x2", (char *)"-smooth", (char *)"50",
|
||||
(char *)"-targa", NULL
|
||||
(char *)"-targa"
|
||||
};
|
||||
int fd = -1;
|
||||
FILE *file = NULL;
|
||||
|
||||
snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_cjpeg_fuzz.XXXXXX");
|
||||
if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0)
|
||||
if ((file = fmemopen((void *)data, size, "r")) == NULL)
|
||||
goto bailout;
|
||||
|
||||
argv1[12] = argv2[13] = filename;
|
||||
fseek(file, 0, SEEK_SET);
|
||||
cjpeg_fuzzer(12, argv1, file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
cjpeg_fuzzer(13, argv2, file);
|
||||
|
||||
cjpeg_main(13, argv1);
|
||||
cjpeg_main(14, argv2);
|
||||
argv1[11] = argv2[12] = NULL;
|
||||
|
||||
argv1[12] = argv2[13] = NULL;
|
||||
argv1[11] = argv2[12] = filename;
|
||||
|
||||
cjpeg_main(12, argv1);
|
||||
cjpeg_main(13, argv2);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
cjpeg_fuzzer(11, argv1, file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
cjpeg_fuzzer(12, argv2, file);
|
||||
|
||||
bailout:
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
if (strlen(filename) > 0) unlink(filename);
|
||||
}
|
||||
if (file) fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" unsigned char *
|
||||
_tj3LoadImageFromFileHandle8(tjhandle handle, FILE *file, int *width,
|
||||
int align, int *height, int *pixelFormat);
|
||||
|
||||
|
||||
#define NUMTESTS 7
|
||||
|
||||
@@ -48,8 +52,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
tjhandle handle = NULL;
|
||||
unsigned char *srcBuf = NULL, *dstBuf = NULL;
|
||||
int width = 0, height = 0, fd = -1, ti;
|
||||
char filename[FILENAME_MAX] = { 0 };
|
||||
int width = 0, height = 0, ti;
|
||||
FILE *file = NULL;
|
||||
struct test tests[NUMTESTS] = {
|
||||
{ TJPF_RGB, TJSAMP_444, 100 },
|
||||
{ TJPF_BGR, TJSAMP_422, 90 },
|
||||
@@ -60,8 +64,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{ TJPF_CMYK, TJSAMP_440, 40 }
|
||||
};
|
||||
|
||||
snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_fuzz.XXXXXX");
|
||||
if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0)
|
||||
if ((file = fmemopen((void *)data, size, "r")) == NULL)
|
||||
goto bailout;
|
||||
|
||||
if ((handle = tj3Init(TJINIT_COMPRESS)) == NULL)
|
||||
@@ -83,8 +86,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
tj3Set(handle, TJPARAM_MAXPIXELS, 1048576);
|
||||
/* tj3LoadImage8() will refuse to load images larger than 1 Megapixel, so
|
||||
we don't need to check the width and height here. */
|
||||
if ((srcBuf = tj3LoadImage8(handle, filename, &width, 1, &height,
|
||||
&pf)) == NULL)
|
||||
fseek(file, 0, SEEK_SET);
|
||||
if ((srcBuf = _tj3LoadImageFromFileHandle8(handle, file, &width, 1,
|
||||
&height, &pf)) == NULL)
|
||||
continue;
|
||||
|
||||
dstSize = maxBufSize = tj3JPEGBufSize(width, height, tests[ti].subsamp);
|
||||
@@ -118,10 +122,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
bailout:
|
||||
tj3Free(dstBuf);
|
||||
tj3Free(srcBuf);
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
if (strlen(filename) > 0) unlink(filename);
|
||||
}
|
||||
if (file) fclose(file);
|
||||
tj3Destroy(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" short *
|
||||
_tj3LoadImageFromFileHandle12(tjhandle handle, FILE *file, int *width,
|
||||
int align, int *height, int *pixelFormat);
|
||||
|
||||
|
||||
#define NUMTESTS 7
|
||||
|
||||
@@ -49,8 +53,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
tjhandle handle = NULL;
|
||||
short *srcBuf = NULL;
|
||||
unsigned char *dstBuf = NULL;
|
||||
int width = 0, height = 0, fd = -1, ti;
|
||||
char filename[FILENAME_MAX] = { 0 };
|
||||
int width = 0, height = 0, ti;
|
||||
FILE *file = NULL;
|
||||
struct test tests[NUMTESTS] = {
|
||||
{ TJPF_RGB, TJSAMP_444, 100 },
|
||||
{ TJPF_BGR, TJSAMP_422, 90 },
|
||||
@@ -61,8 +65,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{ TJPF_CMYK, TJSAMP_440, 40 }
|
||||
};
|
||||
|
||||
snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress12_fuzz.XXXXXX");
|
||||
if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0)
|
||||
if ((file = fmemopen((void *)data, size, "r")) == NULL)
|
||||
goto bailout;
|
||||
|
||||
if ((handle = tj3Init(TJINIT_COMPRESS)) == NULL)
|
||||
@@ -83,8 +86,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
tj3Set(handle, TJPARAM_MAXPIXELS, 1048576);
|
||||
/* tj3LoadImage12() will refuse to load images larger than 1 Megapixel, so
|
||||
we don't need to check the width and height here. */
|
||||
if ((srcBuf = tj3LoadImage12(handle, filename, &width, 1, &height,
|
||||
&pf)) == NULL)
|
||||
fseek(file, 0, SEEK_SET);
|
||||
if ((srcBuf = _tj3LoadImageFromFileHandle12(handle, file, &width, 1,
|
||||
&height, &pf)) == NULL)
|
||||
continue;
|
||||
|
||||
dstSize = maxBufSize = tj3JPEGBufSize(width, height, tests[ti].subsamp);
|
||||
@@ -118,10 +122,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
bailout:
|
||||
tj3Free(dstBuf);
|
||||
tj3Free(srcBuf);
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
if (strlen(filename) > 0) unlink(filename);
|
||||
}
|
||||
if (file) fclose(file);
|
||||
tj3Destroy(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" short *
|
||||
_tj3LoadImageFromFileHandle12(tjhandle handle, FILE *file, int *width,
|
||||
int align, int *height, int *pixelFormat);
|
||||
|
||||
|
||||
#define NUMTESTS 7
|
||||
|
||||
@@ -48,8 +52,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
tjhandle handle = NULL;
|
||||
short *srcBuf = NULL;
|
||||
unsigned char *dstBuf = NULL;
|
||||
int width = 0, height = 0, fd = -1, ti;
|
||||
char filename[FILENAME_MAX] = { 0 };
|
||||
int width = 0, height = 0, ti;
|
||||
FILE *file = NULL;
|
||||
struct test tests[NUMTESTS] = {
|
||||
{ TJPF_RGB, 12, 1, 0 },
|
||||
{ TJPF_BGR, 11, 2, 2 },
|
||||
@@ -60,8 +64,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{ TJPF_CMYK, 12, 7, 0 }
|
||||
};
|
||||
|
||||
snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_fuzz.XXXXXX");
|
||||
if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0)
|
||||
if ((file = fmemopen((void *)data, size, "r")) == NULL)
|
||||
goto bailout;
|
||||
|
||||
if ((handle = tj3Init(TJINIT_COMPRESS)) == NULL)
|
||||
@@ -80,8 +83,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
tj3Set(handle, TJPARAM_MAXPIXELS, 1048576);
|
||||
/* tj3LoadImage12() will refuse to load images larger than 1 Megapixel, so
|
||||
we don't need to check the width and height here. */
|
||||
if ((srcBuf = tj3LoadImage12(handle, filename, &width, 1, &height,
|
||||
&pf)) == NULL)
|
||||
fseek(file, 0, SEEK_SET);
|
||||
if ((srcBuf = _tj3LoadImageFromFileHandle12(handle, file, &width, 1,
|
||||
&height, &pf)) == NULL)
|
||||
continue;
|
||||
|
||||
dstSize = maxBufSize = tj3JPEGBufSize(width, height, TJSAMP_444);
|
||||
@@ -116,10 +120,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
bailout:
|
||||
tj3Free(dstBuf);
|
||||
tj3Free(srcBuf);
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
if (strlen(filename) > 0) unlink(filename);
|
||||
}
|
||||
if (file) fclose(file);
|
||||
tj3Destroy(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" unsigned short *
|
||||
_tj3LoadImageFromFileHandle16(tjhandle handle, FILE *file, int *width,
|
||||
int align, int *height, int *pixelFormat);
|
||||
|
||||
|
||||
#define NUMTESTS 7
|
||||
|
||||
@@ -48,8 +52,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
tjhandle handle = NULL;
|
||||
unsigned short *srcBuf = NULL;
|
||||
unsigned char *dstBuf = NULL;
|
||||
int width = 0, height = 0, fd = -1, ti;
|
||||
char filename[FILENAME_MAX] = { 0 };
|
||||
int width = 0, height = 0, ti;
|
||||
FILE *file = NULL;
|
||||
struct test tests[NUMTESTS] = {
|
||||
{ TJPF_RGB, 16, 1, 0 },
|
||||
{ TJPF_BGR, 15, 2, 2 },
|
||||
@@ -60,8 +64,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{ TJPF_CMYK, 16, 7, 0 }
|
||||
};
|
||||
|
||||
snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_fuzz.XXXXXX");
|
||||
if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0)
|
||||
if ((file = fmemopen((void *)data, size, "r")) == NULL)
|
||||
goto bailout;
|
||||
|
||||
if ((handle = tj3Init(TJINIT_COMPRESS)) == NULL)
|
||||
@@ -80,8 +83,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
tj3Set(handle, TJPARAM_MAXPIXELS, 1048576);
|
||||
/* tj3LoadImage16() will refuse to load images larger than 1 Megapixel, so
|
||||
we don't need to check the width and height here. */
|
||||
if ((srcBuf = tj3LoadImage16(handle, filename, &width, 1, &height,
|
||||
&pf)) == NULL)
|
||||
fseek(file, 0, SEEK_SET);
|
||||
if ((srcBuf = _tj3LoadImageFromFileHandle16(handle, file, &width, 1,
|
||||
&height, &pf)) == NULL)
|
||||
continue;
|
||||
|
||||
dstSize = maxBufSize = tj3JPEGBufSize(width, height, TJSAMP_444);
|
||||
@@ -116,10 +120,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
bailout:
|
||||
tj3Free(dstBuf);
|
||||
tj3Free(srcBuf);
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
if (strlen(filename) > 0) unlink(filename);
|
||||
}
|
||||
if (file) fclose(file);
|
||||
tj3Destroy(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" unsigned char *
|
||||
_tj3LoadImageFromFileHandle8(tjhandle handle, FILE *file, int *width,
|
||||
int align, int *height, int *pixelFormat);
|
||||
|
||||
|
||||
#define NUMTESTS 7
|
||||
|
||||
@@ -47,8 +51,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
tjhandle handle = NULL;
|
||||
unsigned char *srcBuf = NULL, *dstBuf = NULL;
|
||||
int width = 0, height = 0, fd = -1, ti;
|
||||
char filename[FILENAME_MAX] = { 0 };
|
||||
int width = 0, height = 0, ti;
|
||||
FILE *file = NULL;
|
||||
struct test tests[NUMTESTS] = {
|
||||
{ TJPF_RGB, 8, 1, 0 },
|
||||
{ TJPF_BGR, 7, 2, 5 },
|
||||
@@ -59,8 +63,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{ TJPF_CMYK, 2, 7, 0 }
|
||||
};
|
||||
|
||||
snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_fuzz.XXXXXX");
|
||||
if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0)
|
||||
if ((file = fmemopen((void *)data, size, "r")) == NULL)
|
||||
goto bailout;
|
||||
|
||||
if ((handle = tj3Init(TJINIT_COMPRESS)) == NULL)
|
||||
@@ -79,8 +82,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
tj3Set(handle, TJPARAM_MAXPIXELS, 1048576);
|
||||
/* tj3LoadImage8() will refuse to load images larger than 1 Megapixel, so
|
||||
we don't need to check the width and height here. */
|
||||
if ((srcBuf = tj3LoadImage8(handle, filename, &width, 1, &height,
|
||||
&pf)) == NULL)
|
||||
fseek(file, 0, SEEK_SET);
|
||||
if ((srcBuf = _tj3LoadImageFromFileHandle8(handle, file, &width, 1,
|
||||
&height, &pf)) == NULL)
|
||||
continue;
|
||||
|
||||
dstSize = maxBufSize = tj3JPEGBufSize(width, height, TJSAMP_444);
|
||||
@@ -115,10 +119,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
bailout:
|
||||
tj3Free(dstBuf);
|
||||
tj3Free(srcBuf);
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
if (strlen(filename) > 0) unlink(filename);
|
||||
}
|
||||
if (file) fclose(file);
|
||||
tj3Destroy(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" unsigned char *
|
||||
_tj3LoadImageFromFileHandle8(tjhandle handle, FILE *file, int *width,
|
||||
int align, int *height, int *pixelFormat);
|
||||
|
||||
|
||||
#define NUMTESTS 6
|
||||
|
||||
@@ -48,8 +52,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
tjhandle handle = NULL;
|
||||
unsigned char *srcBuf = NULL, *dstBuf = NULL, *yuvBuf = NULL;
|
||||
int width = 0, height = 0, fd = -1, ti;
|
||||
char filename[FILENAME_MAX] = { 0 };
|
||||
int width = 0, height = 0, ti;
|
||||
FILE *file = NULL;
|
||||
struct test tests[NUMTESTS] = {
|
||||
{ TJPF_XBGR, TJSAMP_444, 100 },
|
||||
{ TJPF_XRGB, TJSAMP_422, 90 },
|
||||
@@ -59,8 +63,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{ TJPF_GRAY, TJSAMP_GRAY, 50 }
|
||||
};
|
||||
|
||||
snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_yuv_fuzz.XXXXXX");
|
||||
if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0)
|
||||
if ((file = fmemopen((void *)data, size, "r")) == NULL)
|
||||
goto bailout;
|
||||
|
||||
if ((handle = tj3Init(TJINIT_COMPRESS)) == NULL)
|
||||
@@ -82,8 +85,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
tj3Set(handle, TJPARAM_MAXPIXELS, 1048576);
|
||||
/* tj3LoadImage8() will refuse to load images larger than 1 Megapixel, so
|
||||
we don't need to check the width and height here. */
|
||||
if ((srcBuf = tj3LoadImage8(handle, filename, &width, 1, &height,
|
||||
&pf)) == NULL)
|
||||
fseek(file, 0, SEEK_SET);
|
||||
if ((srcBuf = _tj3LoadImageFromFileHandle8(handle, file, &width, 1,
|
||||
&height, &pf)) == NULL)
|
||||
continue;
|
||||
|
||||
dstSize = maxBufSize = tj3JPEGBufSize(width, height, tests[ti].subsamp);
|
||||
@@ -123,10 +127,7 @@ bailout:
|
||||
tj3Free(dstBuf);
|
||||
free(yuvBuf);
|
||||
tj3Free(srcBuf);
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
if (strlen(filename) > 0) unlink(filename);
|
||||
}
|
||||
if (file) fclose(file);
|
||||
tj3Destroy(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
17
src/cjpeg.c
17
src/cjpeg.c
@@ -7,7 +7,7 @@
|
||||
* Lossless JPEG Modifications:
|
||||
* Copyright (C) 1999, Ken Murchison.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, 2013-2014, 2017, 2019-2022, 2024-2025,
|
||||
* Copyright (C) 2010, 2013-2014, 2017, 2019-2022, 2024-2026,
|
||||
* D. R. Commander.
|
||||
* For conditions of distribution and use, see the accompanying README.ijg
|
||||
* file.
|
||||
@@ -162,7 +162,7 @@ struct my_error_mgr {
|
||||
jmp_buf setjmp_buffer;
|
||||
};
|
||||
|
||||
void my_error_exit(j_common_ptr cinfo)
|
||||
static void my_error_exit(j_common_ptr cinfo)
|
||||
{
|
||||
struct my_error_mgr *myerr = (struct my_error_mgr *)cinfo->err;
|
||||
|
||||
@@ -182,8 +182,6 @@ static void my_emit_message_fuzzer(j_common_ptr cinfo, int msg_level)
|
||||
jpeg_abort_compress(&cinfo); \
|
||||
} \
|
||||
jpeg_destroy_compress(&cinfo); \
|
||||
if (input_file != stdin && input_file != NULL) \
|
||||
fclose(input_file); \
|
||||
if (memdst) \
|
||||
free(outbuffer); \
|
||||
free(icc_profile); \
|
||||
@@ -616,8 +614,13 @@ my_emit_message(j_common_ptr cinfo, int msg_level)
|
||||
* The main program.
|
||||
*/
|
||||
|
||||
#ifdef CJPEG_FUZZER
|
||||
static int
|
||||
cjpeg_fuzzer(int argc, char **argv, FILE *input_file)
|
||||
#else
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
#endif
|
||||
{
|
||||
struct jpeg_compress_struct cinfo;
|
||||
#ifdef CJPEG_FUZZER
|
||||
@@ -629,7 +632,9 @@ main(int argc, char **argv)
|
||||
struct cdjpeg_progress_mgr progress;
|
||||
int file_index;
|
||||
cjpeg_source_ptr src_mgr;
|
||||
#ifndef CJPEG_FUZZER
|
||||
FILE *input_file = NULL;
|
||||
#endif
|
||||
FILE *icc_file;
|
||||
JOCTET *icc_profile = NULL;
|
||||
long icc_len = 0;
|
||||
@@ -696,6 +701,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
#endif /* TWO_FILE_COMMANDLINE */
|
||||
|
||||
#ifndef CJPEG_FUZZER
|
||||
/* Open the input file. */
|
||||
if (file_index < argc) {
|
||||
if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) {
|
||||
@@ -706,6 +712,7 @@ main(int argc, char **argv)
|
||||
/* default input file is stdin */
|
||||
input_file = read_stdin();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Open the output file. */
|
||||
if (outfilename != NULL) {
|
||||
@@ -818,8 +825,10 @@ main(int argc, char **argv)
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
|
||||
/* Close files, if we opened them */
|
||||
#ifndef CJPEG_FUZZER
|
||||
if (input_file != stdin)
|
||||
fclose(input_file);
|
||||
#endif
|
||||
if (output_file != stdout && output_file != NULL)
|
||||
fclose(output_file);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2009-2025 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2009-2026 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -290,8 +290,11 @@ bailout:
|
||||
/*************************** Packed-Pixel Image I/O **************************/
|
||||
|
||||
/* TurboJPEG 3.0+ */
|
||||
DLLEXPORT _JSAMPLE *GET_NAME(tj3LoadImage, BITS_IN_JSAMPLE)
|
||||
(tjhandle handle, const char *filename, int *width, int align, int *height,
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
static
|
||||
#endif
|
||||
_JSAMPLE *GET_NAME(_tj3LoadImageFromFileHandle, BITS_IN_JSAMPLE)
|
||||
(tjhandle handle, FILE *file, int *width, int align, int *height,
|
||||
int *pixelFormat)
|
||||
{
|
||||
static const char FUNCTION_NAME[] =
|
||||
@@ -306,12 +309,11 @@ DLLEXPORT _JSAMPLE *GET_NAME(tj3LoadImage, BITS_IN_JSAMPLE)
|
||||
j_compress_ptr cinfo = NULL;
|
||||
cjpeg_source_ptr src;
|
||||
_JSAMPLE *dstBuf = NULL;
|
||||
FILE *file = NULL;
|
||||
boolean invert;
|
||||
|
||||
GET_TJINSTANCE(handle, NULL)
|
||||
|
||||
if (!filename || !width || align < 1 || !height || !pixelFormat ||
|
||||
if (!file || !width || align < 1 || !height || !pixelFormat ||
|
||||
*pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF)
|
||||
THROW("Invalid argument");
|
||||
if ((align & (align - 1)) != 0)
|
||||
@@ -324,13 +326,6 @@ DLLEXPORT _JSAMPLE *GET_NAME(tj3LoadImage, BITS_IN_JSAMPLE)
|
||||
this2 = (tjinstance *)handle2;
|
||||
cinfo = &this2->cinfo;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
if (fopen_s(&file, filename, "rb") || file == NULL)
|
||||
#else
|
||||
if ((file = fopen(filename, "rb")) == NULL)
|
||||
#endif
|
||||
THROW_UNIX("Cannot open input file");
|
||||
|
||||
if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF)
|
||||
THROW_UNIX("Could not read input file")
|
||||
else if (tempc == EOF)
|
||||
@@ -415,6 +410,56 @@ DLLEXPORT _JSAMPLE *GET_NAME(tj3LoadImage, BITS_IN_JSAMPLE)
|
||||
|
||||
bailout:
|
||||
tj3Destroy(handle2);
|
||||
if (retval < 0) { free(dstBuf); dstBuf = NULL; }
|
||||
return dstBuf;
|
||||
|
||||
#else /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */
|
||||
|
||||
static const char ERROR_MSG[] =
|
||||
"16-bit data precision requires lossless JPEG,\n"
|
||||
"which was disabled at build time.";
|
||||
_JSAMPLE *retval = NULL;
|
||||
|
||||
GET_TJINSTANCE(handle, NULL)
|
||||
SNPRINTF(this->errStr, JMSG_LENGTH_MAX, "%s(): %s", FUNCTION_NAME,
|
||||
ERROR_MSG);
|
||||
this->isInstanceError = TRUE; THROWG(ERROR_MSG, NULL)
|
||||
|
||||
bailout:
|
||||
return retval;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
DLLEXPORT _JSAMPLE *GET_NAME(tj3LoadImage, BITS_IN_JSAMPLE)
|
||||
(tjhandle handle, const char *filename, int *width, int align, int *height,
|
||||
int *pixelFormat)
|
||||
{
|
||||
static const char FUNCTION_NAME[] =
|
||||
GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE);
|
||||
|
||||
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
|
||||
|
||||
int retval = 0;
|
||||
_JSAMPLE *dstBuf = NULL;
|
||||
FILE *file = NULL;
|
||||
|
||||
GET_TJINSTANCE(handle, NULL)
|
||||
|
||||
if (!filename)
|
||||
THROW("Invalid argument");
|
||||
|
||||
#ifdef _MSC_VER
|
||||
if (fopen_s(&file, filename, "rb") || file == NULL)
|
||||
#else
|
||||
if ((file = fopen(filename, "rb")) == NULL)
|
||||
#endif
|
||||
THROW_UNIX("Cannot open input file");
|
||||
|
||||
dstBuf = GET_NAME(_tj3LoadImageFromFileHandle, BITS_IN_JSAMPLE)
|
||||
(handle, file, width, align, height, pixelFormat);
|
||||
|
||||
bailout:
|
||||
if (file) fclose(file);
|
||||
if (retval < 0) { free(dstBuf); dstBuf = NULL; }
|
||||
return dstBuf;
|
||||
|
||||
Reference in New Issue
Block a user