diff options
Diffstat (limited to 'cjpeg.c')
-rw-r--r-- | cjpeg.c | 72 |
1 files changed, 68 insertions, 4 deletions
@@ -5,7 +5,7 @@ * Copyright (C) 1991-1998, Thomas G. Lane. * Modified 2003-2011 by Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2010, 2013-2014, 2017, 2019-2020, D. R. Commander. + * Copyright (C) 2010, 2013-2014, 2017, 2019-2021, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -27,6 +27,9 @@ * works regardless of which command line style is used. */ +#ifdef CJPEG_FUZZER +#define JPEG_INTERNALS +#endif #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ #include "jversion.h" /* for version message */ #include "jconfigint.h" @@ -142,8 +145,47 @@ select_file_type(j_compress_ptr cinfo, FILE *infile) static const char *progname; /* program name for error messages */ static char *icc_filename; /* for -icc switch */ static char *outfilename; /* for -outfile switch */ -static boolean memdst; /* for -memdst switch */ -static boolean report; /* for -report switch */ +boolean memdst; /* for -memdst switch */ +boolean report; /* for -report switch */ + + +#ifdef CJPEG_FUZZER + +#include <setjmp.h> + +struct my_error_mgr { + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; +}; + +void my_error_exit(j_common_ptr cinfo) +{ + struct my_error_mgr *myerr = (struct my_error_mgr *)cinfo->err; + + longjmp(myerr->setjmp_buffer, 1); +} + +static void my_emit_message(j_common_ptr cinfo, int msg_level) +{ + if (msg_level < 0) + cinfo->err->num_warnings++; +} + +#define HANDLE_ERROR() { \ + if (cinfo.global_state > CSTATE_START) { \ + if (memdst && outbuffer) \ + (*cinfo.dest->term_destination) (&cinfo); \ + jpeg_abort_compress(&cinfo); \ + } \ + jpeg_destroy_compress(&cinfo); \ + if (input_file != stdin && input_file != NULL) \ + fclose(input_file); \ + if (memdst) \ + free(outbuffer); \ + return EXIT_FAILURE; \ +} + +#endif LOCAL(void) @@ -510,11 +552,16 @@ main(int argc, char **argv) #endif { struct jpeg_compress_struct cinfo; +#ifdef CJPEG_FUZZER + struct my_error_mgr myerr; + struct jpeg_error_mgr &jerr = myerr.pub; +#else struct jpeg_error_mgr jerr; +#endif struct cdjpeg_progress_mgr progress; int file_index; cjpeg_source_ptr src_mgr; - FILE *input_file; + FILE *input_file = NULL; FILE *icc_file; JOCTET *icc_profile = NULL; long icc_len = 0; @@ -632,6 +679,13 @@ main(int argc, char **argv) fclose(icc_file); } +#ifdef CJPEG_FUZZER + jerr.error_exit = my_error_exit; + jerr.emit_message = my_emit_message; + if (setjmp(myerr.setjmp_buffer)) + HANDLE_ERROR() +#endif + if (report) { start_progress_monitor((j_common_ptr)&cinfo, &progress); progress.report = report; @@ -640,6 +694,9 @@ main(int argc, char **argv) /* Figure out the input file format, and set up to read it. */ src_mgr = select_file_type(&cinfo, input_file); src_mgr->input_file = input_file; +#ifdef CJPEG_FUZZER + src_mgr->max_pixels = 1048576; +#endif /* Read the input file header to obtain file size & colorspace. */ (*src_mgr->start_input) (&cinfo, src_mgr); @@ -658,6 +715,11 @@ main(int argc, char **argv) #endif jpeg_stdio_dest(&cinfo, output_file); +#ifdef CJPEG_FUZZER + if (setjmp(myerr.setjmp_buffer)) + HANDLE_ERROR() +#endif + /* Start compressor */ jpeg_start_compress(&cinfo, TRUE); @@ -685,7 +747,9 @@ main(int argc, char **argv) end_progress_monitor((j_common_ptr)&cinfo); if (memdst) { +#ifndef CJPEG_FUZZER fprintf(stderr, "Compressed size: %lu bytes\n", outsize); +#endif free(outbuffer); } |