Ensure methods called by global funcs are init'd

If a hypothetical calling application does something really stupid and
changes cinfo->data_precision after calling jpeg_start_*compress(), then
the precision-specific methods called by jpeg_write_scanlines(),
jpeg_write_raw_data(), jpeg_finish_compress(), jpeg_read_scanlines(),
jpeg_read_raw_data(), or jpeg_start_output() may not be initialized.

Ensure that the first precision-specific method (which will always be
cinfo->main->process_data*(), cinfo->coef->compress_data*(), or
cinfo->coef->decompress_data()) called by any global function that may
be called after jpeg_start_*compress() is initialized and non-NULL.
This increases the likelihood (but does not guarantee) that a
hypothetical stupid calling application will fail gracefully rather than
segfault if it changes cinfo->data_precision after calling
jpeg_start_*compress().  A hypothetical stupid calling application can
still bork itself by changing cinfo->data_precision after initializing
the source manager but before calling jpeg_start_compress(), or after
initializing the destination manager but before calling
jpeg_start_decompress().
This commit is contained in:
DRC
2024-12-18 12:50:38 -05:00
parent 3e703af408
commit e81cb16e0f
8 changed files with 41 additions and 10 deletions

View File

@@ -19,6 +19,11 @@ was previously enabled in a libjpeg or TurboJPEG instance.
instance, and setting `TJPARAM_LOSSLESS`/`TJ.PARAM_LOSSLESS` to `0` now
disables lossless JPEG compression in a TurboJPEG instance.
4. Hardened the libjpeg API against hypothetical calling applications that may
erroneously change the value of the `data_precision` field in
`jpeg_compress_struct` or `jpeg_decompress_struct` after calling
`jpeg_start_compress()` or `jpeg_start_decompress()`.
3.0.4
=====

View File

@@ -5,7 +5,7 @@
* Copyright (C) 1994-1998, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2022, D. R. Commander.
* Copyright (C) 2022, 2024, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -196,15 +196,21 @@ jpeg_finish_compress(j_compress_ptr cinfo)
*/
if (cinfo->data_precision == 16) {
#ifdef C_LOSSLESS_SUPPORTED
if (cinfo->coef->compress_data_16 == NULL)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
if (!(*cinfo->coef->compress_data_16) (cinfo, (J16SAMPIMAGE)NULL))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
#endif
} else if (cinfo->data_precision == 12) {
if (cinfo->coef->compress_data_12 == NULL)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
if (!(*cinfo->coef->compress_data_12) (cinfo, (J12SAMPIMAGE)NULL))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
} else {
if (cinfo->coef->compress_data == NULL)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
if (!(*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE)NULL))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
}

View File

@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1996, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2022, D. R. Commander.
* Copyright (C) 2022, 2024, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -117,6 +117,8 @@ _jpeg_write_scanlines(j_compress_ptr cinfo, _JSAMPARRAY scanlines,
num_lines = rows_left;
row_ctr = 0;
if (cinfo->main->_process_data == NULL)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
(*cinfo->main->_process_data) (cinfo, scanlines, &row_ctr, num_lines);
cinfo->next_scanline += row_ctr;
return row_ctr;
@@ -174,6 +176,8 @@ _jpeg_write_raw_data(j_compress_ptr cinfo, _JSAMPIMAGE data,
ERREXIT(cinfo, JERR_BUFFER_SIZE);
/* Directly compress the row. */
if (cinfo->coef->_compress_data == NULL)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
if (!(*cinfo->coef->_compress_data) (cinfo, data)) {
/* If compressor did not consume the whole row, suspend processing. */
return 0;

View File

@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2022, D. R. Commander.
* Copyright (C) 2022, 2024, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -414,6 +414,7 @@ _jinit_c_coef_controller(j_compress_ptr cinfo, boolean need_full_buffer)
coef = (my_coef_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(my_coef_controller));
memset(coef, 0, sizeof(my_coef_controller));
cinfo->coef = (struct jpeg_c_coef_controller *)coef;
coef->pub.start_pass = start_pass_coef;

View File

@@ -6,7 +6,7 @@
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2022, D. R. Commander.
* Copyright (C) 2022, 2024, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -146,6 +146,7 @@ _jinit_c_main_controller(j_compress_ptr cinfo, boolean need_full_buffer)
main_ptr = (my_main_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(my_main_controller));
memset(main_ptr, 0, sizeof(my_main_controller));
cinfo->main = (struct jpeg_c_main_controller *)main_ptr;
main_ptr->pub.start_pass = start_pass_main;

View File

@@ -128,20 +128,28 @@ output_pass_setup(j_decompress_ptr cinfo)
}
/* Process some data */
last_scanline = cinfo->output_scanline;
if (cinfo->data_precision == 16) {
#ifdef D_LOSSLESS_SUPPORTED
if (cinfo->data_precision == 16)
if (cinfo->main->process_data_16 == NULL)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
(*cinfo->main->process_data_16) (cinfo, (J16SAMPARRAY)NULL,
&cinfo->output_scanline,
(JDIMENSION)0);
else
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
#endif
if (cinfo->data_precision == 12)
} else if (cinfo->data_precision == 12) {
if (cinfo->main->process_data_12 == NULL)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
(*cinfo->main->process_data_12) (cinfo, (J12SAMPARRAY)NULL,
&cinfo->output_scanline,
(JDIMENSION)0);
else
} else {
if (cinfo->main->process_data == NULL)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
(*cinfo->main->process_data) (cinfo, (JSAMPARRAY)NULL,
&cinfo->output_scanline, (JDIMENSION)0);
}
if (cinfo->output_scanline == last_scanline)
return FALSE; /* No progress made, must suspend */
}
@@ -333,6 +341,8 @@ _jpeg_read_scanlines(j_decompress_ptr cinfo, _JSAMPARRAY scanlines,
/* Process some data */
row_ctr = 0;
if (cinfo->main->_process_data == NULL)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
(*cinfo->main->_process_data) (cinfo, scanlines, &row_ctr, max_lines);
cinfo->output_scanline += row_ctr;
return row_ctr;
@@ -679,6 +689,8 @@ _jpeg_read_raw_data(j_decompress_ptr cinfo, _JSAMPIMAGE data,
ERREXIT(cinfo, JERR_BUFFER_SIZE);
/* Decompress directly into user's buffer. */
if (cinfo->coef->_decompress_data == NULL)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
if (!(*cinfo->coef->_decompress_data) (cinfo, data))
return 0; /* suspension forced, can do nothing more */

View File

@@ -5,7 +5,7 @@
* Copyright (C) 1994-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2010, 2015-2016, 2019-2020, 2022-2023, D. R. Commander.
* Copyright (C) 2010, 2015-2016, 2019-2020, 2022-2024, D. R. Commander.
* Copyright (C) 2015, 2020, Google, Inc.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
@@ -824,6 +824,7 @@ _jinit_d_coef_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
coef = (my_coef_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(my_coef_controller));
memset(coef, 0, sizeof(my_coef_controller));
cinfo->coef = (struct jpeg_d_coef_controller *)coef;
coef->pub.start_input_pass = start_input_pass;
coef->pub.start_output_pass = start_output_pass;

View File

@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1996, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2010, 2016, 2022, D. R. Commander.
* Copyright (C) 2010, 2016, 2022, 2024, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -437,6 +437,7 @@ _jinit_d_main_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
main_ptr = (my_main_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(my_main_controller));
memset(main_ptr, 0, sizeof(my_main_controller));
cinfo->main = (struct jpeg_d_main_controller *)main_ptr;
main_ptr->pub.start_pass = start_pass_main;