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.
diff --git a/ChangeLog.md b/ChangeLog.md
index 8d9d31a..7902d46 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -25,6 +25,10 @@
time. This allows both AltiVec-equipped and non-AltiVec-equipped CPUs to be
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
=====
diff --git a/cjpeg.1 b/cjpeg.1
index 569dc3f..75a9cce 100644
--- a/cjpeg.1
+++ b/cjpeg.1
@@ -1,4 +1,4 @@
-.TH CJPEG 1 "4 November 2020"
+.TH CJPEG 1 "18 November 2021"
.SH NAME
cjpeg \- compress an image file to a JPEG file
.SH SYNOPSIS
@@ -226,6 +226,11 @@
.BI \-report
Report compression progress.
.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
Enable debug printout. More
.BR \-v 's
diff --git a/cjpeg.c b/cjpeg.c
index c99a133..b299df6 100644
--- a/cjpeg.c
+++ b/cjpeg.c
@@ -147,6 +147,7 @@
static char *outfilename; /* for -outfile switch */
boolean memdst; /* for -memdst switch */
boolean report; /* for -report switch */
+boolean strict; /* for -strict switch */
#ifdef CJPEG_FUZZER
@@ -240,6 +241,7 @@
fprintf(stderr, " -memdst Compress to memory instead of file (useful for benchmarking)\n");
#endif
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, " -version Print version information and exit\n");
fprintf(stderr, "Switches for wizards:\n");
@@ -285,6 +287,7 @@
outfilename = NULL;
memdst = FALSE;
report = FALSE;
+ strict = FALSE;
cinfo->err->trace_level = 0;
/* Scan command line options, adjust parameters */
@@ -493,6 +496,9 @@
usage();
cinfo->smoothing_factor = val;
+ } else if (keymatch(arg, "strict", 2)) {
+ strict = TRUE;
+
} else if (keymatch(arg, "targa", 1)) {
/* Input file is Targa format. */
is_targa = TRUE;
@@ -540,6 +546,19 @@
}
+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.
*/
@@ -600,6 +619,9 @@
file_index = parse_switches(&cinfo, argc, argv, 0, FALSE);
+ if (strict)
+ jerr.emit_message = my_emit_message;
+
#ifdef TWO_FILE_COMMANDLINE
if (!memdst) {
/* Must have either -outfile switch or explicit output file name */