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:
@@ -19,6 +19,11 @@ was previously enabled in a libjpeg or TurboJPEG instance.
|
|||||||
instance, and setting `TJPARAM_LOSSLESS`/`TJ.PARAM_LOSSLESS` to `0` now
|
instance, and setting `TJPARAM_LOSSLESS`/`TJ.PARAM_LOSSLESS` to `0` now
|
||||||
disables lossless JPEG compression in a TurboJPEG instance.
|
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
|
3.0.4
|
||||||
=====
|
=====
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* Copyright (C) 1994-1998, Thomas G. Lane.
|
* Copyright (C) 1994-1998, Thomas G. Lane.
|
||||||
* Modified 2003-2010 by Guido Vollbeding.
|
* Modified 2003-2010 by Guido Vollbeding.
|
||||||
* libjpeg-turbo Modifications:
|
* 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
|
* For conditions of distribution and use, see the accompanying README.ijg
|
||||||
* file.
|
* file.
|
||||||
*
|
*
|
||||||
@@ -196,15 +196,21 @@ jpeg_finish_compress(j_compress_ptr cinfo)
|
|||||||
*/
|
*/
|
||||||
if (cinfo->data_precision == 16) {
|
if (cinfo->data_precision == 16) {
|
||||||
#ifdef C_LOSSLESS_SUPPORTED
|
#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))
|
if (!(*cinfo->coef->compress_data_16) (cinfo, (J16SAMPIMAGE)NULL))
|
||||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
||||||
#else
|
#else
|
||||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||||
#endif
|
#endif
|
||||||
} else if (cinfo->data_precision == 12) {
|
} 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))
|
if (!(*cinfo->coef->compress_data_12) (cinfo, (J12SAMPIMAGE)NULL))
|
||||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
||||||
} else {
|
} else {
|
||||||
|
if (cinfo->coef->compress_data == NULL)
|
||||||
|
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||||
if (!(*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE)NULL))
|
if (!(*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE)NULL))
|
||||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* This file was part of the Independent JPEG Group's software:
|
* This file was part of the Independent JPEG Group's software:
|
||||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||||
* libjpeg-turbo Modifications:
|
* 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
|
* For conditions of distribution and use, see the accompanying README.ijg
|
||||||
* file.
|
* file.
|
||||||
*
|
*
|
||||||
@@ -117,6 +117,8 @@ _jpeg_write_scanlines(j_compress_ptr cinfo, _JSAMPARRAY scanlines,
|
|||||||
num_lines = rows_left;
|
num_lines = rows_left;
|
||||||
|
|
||||||
row_ctr = 0;
|
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->main->_process_data) (cinfo, scanlines, &row_ctr, num_lines);
|
||||||
cinfo->next_scanline += row_ctr;
|
cinfo->next_scanline += row_ctr;
|
||||||
return row_ctr;
|
return row_ctr;
|
||||||
@@ -174,6 +176,8 @@ _jpeg_write_raw_data(j_compress_ptr cinfo, _JSAMPIMAGE data,
|
|||||||
ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
||||||
|
|
||||||
/* Directly compress the row. */
|
/* 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 (!(*cinfo->coef->_compress_data) (cinfo, data)) {
|
||||||
/* If compressor did not consume the whole row, suspend processing. */
|
/* If compressor did not consume the whole row, suspend processing. */
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* This file was part of the Independent JPEG Group's software:
|
* This file was part of the Independent JPEG Group's software:
|
||||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
* Copyright (C) 1994-1997, Thomas G. Lane.
|
||||||
* libjpeg-turbo Modifications:
|
* 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
|
* For conditions of distribution and use, see the accompanying README.ijg
|
||||||
* file.
|
* file.
|
||||||
*
|
*
|
||||||
@@ -414,6 +414,7 @@ _jinit_c_coef_controller(j_compress_ptr cinfo, boolean need_full_buffer)
|
|||||||
coef = (my_coef_ptr)
|
coef = (my_coef_ptr)
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||||
sizeof(my_coef_controller));
|
sizeof(my_coef_controller));
|
||||||
|
memset(coef, 0, sizeof(my_coef_controller));
|
||||||
cinfo->coef = (struct jpeg_c_coef_controller *)coef;
|
cinfo->coef = (struct jpeg_c_coef_controller *)coef;
|
||||||
coef->pub.start_pass = start_pass_coef;
|
coef->pub.start_pass = start_pass_coef;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Lossless JPEG Modifications:
|
* Lossless JPEG Modifications:
|
||||||
* Copyright (C) 1999, Ken Murchison.
|
* Copyright (C) 1999, Ken Murchison.
|
||||||
* libjpeg-turbo Modifications:
|
* 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
|
* For conditions of distribution and use, see the accompanying README.ijg
|
||||||
* file.
|
* file.
|
||||||
*
|
*
|
||||||
@@ -146,6 +146,7 @@ _jinit_c_main_controller(j_compress_ptr cinfo, boolean need_full_buffer)
|
|||||||
main_ptr = (my_main_ptr)
|
main_ptr = (my_main_ptr)
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||||
sizeof(my_main_controller));
|
sizeof(my_main_controller));
|
||||||
|
memset(main_ptr, 0, sizeof(my_main_controller));
|
||||||
cinfo->main = (struct jpeg_c_main_controller *)main_ptr;
|
cinfo->main = (struct jpeg_c_main_controller *)main_ptr;
|
||||||
main_ptr->pub.start_pass = start_pass_main;
|
main_ptr->pub.start_pass = start_pass_main;
|
||||||
|
|
||||||
|
|||||||
20
jdapistd.c
20
jdapistd.c
@@ -128,20 +128,28 @@ output_pass_setup(j_decompress_ptr cinfo)
|
|||||||
}
|
}
|
||||||
/* Process some data */
|
/* Process some data */
|
||||||
last_scanline = cinfo->output_scanline;
|
last_scanline = cinfo->output_scanline;
|
||||||
|
if (cinfo->data_precision == 16) {
|
||||||
#ifdef D_LOSSLESS_SUPPORTED
|
#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->main->process_data_16) (cinfo, (J16SAMPARRAY)NULL,
|
||||||
&cinfo->output_scanline,
|
&cinfo->output_scanline,
|
||||||
(JDIMENSION)0);
|
(JDIMENSION)0);
|
||||||
else
|
#else
|
||||||
|
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||||
#endif
|
#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->main->process_data_12) (cinfo, (J12SAMPARRAY)NULL,
|
||||||
&cinfo->output_scanline,
|
&cinfo->output_scanline,
|
||||||
(JDIMENSION)0);
|
(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->main->process_data) (cinfo, (JSAMPARRAY)NULL,
|
||||||
&cinfo->output_scanline, (JDIMENSION)0);
|
&cinfo->output_scanline, (JDIMENSION)0);
|
||||||
|
}
|
||||||
if (cinfo->output_scanline == last_scanline)
|
if (cinfo->output_scanline == last_scanline)
|
||||||
return FALSE; /* No progress made, must suspend */
|
return FALSE; /* No progress made, must suspend */
|
||||||
}
|
}
|
||||||
@@ -333,6 +341,8 @@ _jpeg_read_scanlines(j_decompress_ptr cinfo, _JSAMPARRAY scanlines,
|
|||||||
|
|
||||||
/* Process some data */
|
/* Process some data */
|
||||||
row_ctr = 0;
|
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->main->_process_data) (cinfo, scanlines, &row_ctr, max_lines);
|
||||||
cinfo->output_scanline += row_ctr;
|
cinfo->output_scanline += row_ctr;
|
||||||
return row_ctr;
|
return row_ctr;
|
||||||
@@ -679,6 +689,8 @@ _jpeg_read_raw_data(j_decompress_ptr cinfo, _JSAMPIMAGE data,
|
|||||||
ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
||||||
|
|
||||||
/* Decompress directly into user's buffer. */
|
/* 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))
|
if (!(*cinfo->coef->_decompress_data) (cinfo, data))
|
||||||
return 0; /* suspension forced, can do nothing more */
|
return 0; /* suspension forced, can do nothing more */
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
* Copyright (C) 1994-1997, Thomas G. Lane.
|
||||||
* libjpeg-turbo Modifications:
|
* libjpeg-turbo Modifications:
|
||||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
* 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.
|
* Copyright (C) 2015, 2020, Google, Inc.
|
||||||
* For conditions of distribution and use, see the accompanying README.ijg
|
* For conditions of distribution and use, see the accompanying README.ijg
|
||||||
* file.
|
* file.
|
||||||
@@ -824,6 +824,7 @@ _jinit_d_coef_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
|||||||
coef = (my_coef_ptr)
|
coef = (my_coef_ptr)
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||||
sizeof(my_coef_controller));
|
sizeof(my_coef_controller));
|
||||||
|
memset(coef, 0, sizeof(my_coef_controller));
|
||||||
cinfo->coef = (struct jpeg_d_coef_controller *)coef;
|
cinfo->coef = (struct jpeg_d_coef_controller *)coef;
|
||||||
coef->pub.start_input_pass = start_input_pass;
|
coef->pub.start_input_pass = start_input_pass;
|
||||||
coef->pub.start_output_pass = start_output_pass;
|
coef->pub.start_output_pass = start_output_pass;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* This file was part of the Independent JPEG Group's software:
|
* This file was part of the Independent JPEG Group's software:
|
||||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||||
* libjpeg-turbo Modifications:
|
* 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
|
* For conditions of distribution and use, see the accompanying README.ijg
|
||||||
* file.
|
* file.
|
||||||
*
|
*
|
||||||
@@ -437,6 +437,7 @@ _jinit_d_main_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
|
|||||||
main_ptr = (my_main_ptr)
|
main_ptr = (my_main_ptr)
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||||
sizeof(my_main_controller));
|
sizeof(my_main_controller));
|
||||||
|
memset(main_ptr, 0, sizeof(my_main_controller));
|
||||||
cinfo->main = (struct jpeg_d_main_controller *)main_ptr;
|
cinfo->main = (struct jpeg_d_main_controller *)main_ptr;
|
||||||
main_ptr->pub.start_pass = start_pass_main;
|
main_ptr->pub.start_pass = start_pass_main;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user