1
0
mirror of https://github.com/libjpeg-turbo/libjpeg-turbo.git synced 2026-10-23 11:48:53 +03:00

Compressor: Guard against 0 in quantization tables

... which could cause compute_reciprocal() to divide by 0.  (Minimally,
that is undefined behavior, and on some platforms it will trigger a
floating point exception.)

The most direct way to trigger the issue is by manually modifying the
exposed quantization table values in jpeg_compress_struct just before
calling jpeg_start_compress().  However, referring to #862, a more
indirect way involves using jpeg_read_header() to read a malformed JPEG
header containing quantization tables with values of 0, calling
jpeg_copy_critical_parameters() to transfer those quantization tables
into a compressor instance, and calling jpeg_start_compress().

In both cases, the calling program is abusing the API:

- Applications are supposed to call jpeg_add_quant_table() to pass
  custom quantization tables to the compressor, and
  jpeg_add_quant_table() clamps all values < 1.

- jpeg_copy_critical_parameters() is generally only used with
  transcoding.  Using it with jpeg_start_compress() is only valid when
  the application intends to reuse quantization tables from a
  tables-only datastream, in which case the application must carefully
  control the datastream (as opposed to reading arbitrary data) in order
  to generate a valid image.

Fixes #862
This commit is contained in:
DRC
2026-02-03 14:28:19 -05:00
parent e562849627
commit 2afafb5edd
2 changed files with 14 additions and 2 deletions

View File

@@ -120,6 +120,12 @@ in the same libjpeg instance.
erroneously call `tjCompress*()` or `tjTransform()` with a reused JPEG
destination buffer pointer while specifying a destination buffer size of 0.
19. Hardened the libjpeg API against hypothetical applications that may
erroneously set one of the exposed quantization table values to 0 just before
calling `jpeg_start_compress()`. (This would never happen in a
correctly-written program, because `jpeg_add_quant_table()` clamps all values
less than 1.)
2.0.8 ESR
=========

View File

@@ -6,7 +6,7 @@
* libjpeg-turbo Modifications:
* Copyright (C) 1999-2006, MIYASAKA Masaru.
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2011, 2014-2015, D. R. Commander.
* Copyright (C) 2011, 2014-2015, 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -176,11 +176,17 @@ compute_reciprocal(UINT16 divisor, DCTELEM *dtbl)
UDCTELEM c;
int b, r;
if (divisor == 1) {
if (divisor <= 1) {
/* divisor == 1 means unquantized, so these reciprocal/correction/shift
* values will cause the C quantization algorithm to act like the
* identity function. Since only the C quantization algorithm is used in
* these cases, the scale value is irrelevant.
*
* divisor == 0 can never happen in a normal program, because
* jpeg_add_quant_table() clamps values < 1. However, a program could
* abuse the API by manually modifying the exposed quantization table just
* before calling jpeg_start_compress(). Thus, we effectively clamp
* values < 1 here as well, to avoid dividing by 0.
*/
dtbl[DCTSIZE2 * 0] = (DCTELEM)1; /* reciprocal */
dtbl[DCTSIZE2 * 1] = (DCTELEM)0; /* correction */