cjpeg: Add -strict arg to treat warnings as fatal

This adds fault tolerance to the LZW-compressed GIF reader, which is
the only compression-side code that can throw warnings.
This commit is contained in:
DRC
2021-11-18 21:04:35 -06:00
parent 4c5fa566b3
commit ecf021bc0d
3 changed files with 32 additions and 1 deletions

View File

@@ -25,6 +25,10 @@ FreeBSD/PowerPC systems if AltiVec instructions are not enabled at compile
time. This allows both AltiVec-equipped and non-AltiVec-equipped CPUs to be time. This allows both AltiVec-equipped and non-AltiVec-equipped CPUs to be
supported using the same build of libjpeg-turbo. supported using the same build of libjpeg-turbo.
5. cjpeg now accepts a `-strict` argument similar to that of djpeg and
jpegtran, which causes the compressor to abort if an LZW-compressed GIF input
image contains incomplete or corrupt image data.
2.1.1 2.1.1
===== =====

View File

@@ -1,4 +1,4 @@
.TH CJPEG 1 "4 November 2020" .TH CJPEG 1 "18 November 2021"
.SH NAME .SH NAME
cjpeg \- compress an image file to a JPEG file cjpeg \- compress an image file to a JPEG file
.SH SYNOPSIS .SH SYNOPSIS
@@ -226,6 +226,11 @@ also useful for benchmarking, since it reduces the I/O overhead.
.BI \-report .BI \-report
Report compression progress. Report compression progress.
.TP .TP
.BI \-strict
Treat all warnings as fatal. Enabling this option will cause the compressor to
abort if an LZW-compressed GIF input image contains incomplete or corrupt image
data.
.TP
.B \-verbose .B \-verbose
Enable debug printout. More Enable debug printout. More
.BR \-v 's .BR \-v 's

22
cjpeg.c
View File

@@ -147,6 +147,7 @@ static char *icc_filename; /* for -icc switch */
static char *outfilename; /* for -outfile switch */ static char *outfilename; /* for -outfile switch */
boolean memdst; /* for -memdst switch */ boolean memdst; /* for -memdst switch */
boolean report; /* for -report switch */ boolean report; /* for -report switch */
boolean strict; /* for -strict switch */
#ifdef CJPEG_FUZZER #ifdef CJPEG_FUZZER
@@ -240,6 +241,7 @@ usage(void)
fprintf(stderr, " -memdst Compress to memory instead of file (useful for benchmarking)\n"); fprintf(stderr, " -memdst Compress to memory instead of file (useful for benchmarking)\n");
#endif #endif
fprintf(stderr, " -report Report compression progress\n"); fprintf(stderr, " -report Report compression progress\n");
fprintf(stderr, " -strict Treat all warnings as fatal\n");
fprintf(stderr, " -verbose or -debug Emit debug output\n"); fprintf(stderr, " -verbose or -debug Emit debug output\n");
fprintf(stderr, " -version Print version information and exit\n"); fprintf(stderr, " -version Print version information and exit\n");
fprintf(stderr, "Switches for wizards:\n"); fprintf(stderr, "Switches for wizards:\n");
@@ -285,6 +287,7 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv,
outfilename = NULL; outfilename = NULL;
memdst = FALSE; memdst = FALSE;
report = FALSE; report = FALSE;
strict = FALSE;
cinfo->err->trace_level = 0; cinfo->err->trace_level = 0;
/* Scan command line options, adjust parameters */ /* Scan command line options, adjust parameters */
@@ -493,6 +496,9 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv,
usage(); usage();
cinfo->smoothing_factor = val; cinfo->smoothing_factor = val;
} else if (keymatch(arg, "strict", 2)) {
strict = TRUE;
} else if (keymatch(arg, "targa", 1)) { } else if (keymatch(arg, "targa", 1)) {
/* Input file is Targa format. */ /* Input file is Targa format. */
is_targa = TRUE; is_targa = TRUE;
@@ -540,6 +546,19 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv,
} }
METHODDEF(void)
my_emit_message(j_common_ptr cinfo, int msg_level)
{
if (msg_level < 0) {
/* Treat warning as fatal */
cinfo->err->error_exit(cinfo);
} else {
if (cinfo->err->trace_level >= msg_level)
cinfo->err->output_message(cinfo);
}
}
/* /*
* The main program. * The main program.
*/ */
@@ -600,6 +619,9 @@ main(int argc, char **argv)
file_index = parse_switches(&cinfo, argc, argv, 0, FALSE); file_index = parse_switches(&cinfo, argc, argv, 0, FALSE);
if (strict)
jerr.emit_message = my_emit_message;
#ifdef TWO_FILE_COMMANDLINE #ifdef TWO_FILE_COMMANDLINE
if (!memdst) { if (!memdst) {
/* Must have either -outfile switch or explicit output file name */ /* Must have either -outfile switch or explicit output file name */