Menu

#71 opngreduc.c:957: opng_reduce_to_palette: Assertion `index >= 0' failed.

v1.0 (example)
open-accepted
None
8
2023-11-03
2018-01-04
Henri Salo
No

SHA1: 96fba39b76a07e1f254b8fc4b08e3fd6405e930c

./0.7.7/bin/optipng optipng-opng_reduce_to_palette-abort.png
** Processing: optipng-opng_reduce_to_palette-abort.png
Warning: gAMA: CRC error
Warning: tRNS: CRC error
Warning: tRNS: invalid with alpha channel
Warning: bad adaptive filter value
57x57 pixels, 4x8 bits/pixel, RGB+alpha
optipng: opngreduc.c:957: opng_reduce_to_palette: Assertion `index >= 0' failed.
Aborted

Thanks to Kapsi internet-käyttäjät ry for providing valuable fuzzing resources.

1 Attachments

Discussion

  • Cosmin Truta

    Cosmin Truta - 2018-01-07
    • status: open --> open-accepted
    • assigned_to: Cosmin Truta
     
  • Cosmin Truta

    Cosmin Truta - 2018-01-07

    Hello, and thank you for the defect report.

    The error occurs because of an undetected bad bKGD chunk, with 16-bit color samples in a 8-bit RGB image. The reduction code in opngreduc.c gets confused because it expects valid PNG data from libpng, but libpng fails to perform this particular check.

    Here is the fix that applies to libpng v1.6.34 embedded in OptiPNG v0.7.7. The upstream libpng needs this fix (or a similar fix) also.

    diff --git a/src/libpng/pngrutil.c b/src/libpng/pngrutil.c
    --- a/src/libpng/pngrutil.c
    +++ b/src/libpng/pngrutil.c
    @@ -1997,6 +1997,15 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    
        else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */
        {
    +      if (png_ptr->bit_depth <= 8)
    +      {
    +         if (buf[0] != 0 || buf[1] >= (unsigned int)(1 << png_ptr->bit_depth))
    +         {
    +            png_chunk_benign_error(png_ptr, "invalid gray level");
    +            return;
    +         }
    +      }
    +
           background.index = 0;
           background.red =
           background.green =
    @@ -2006,6 +2015,15 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    
        else
        {
    +      if (png_ptr->bit_depth <= 8)
    +      {
    +         if (buf[0] != 0 || buf[2] != 0 || buf[4] != 0)
    +         {
    +            png_chunk_benign_error(png_ptr, "invalid color");
    +            return;
    +         }
    +      }
    +
           background.index = 0;
           background.red = png_get_uint_16(buf);
           background.green = png_get_uint_16(buf + 2);
    

    Luckily, assertions are never disabled, and, for this reason, the consequence of this defect is a merely inconvenient crash, not as dangerous as it could otherwise have been.

     
  • Andrew

    Andrew - 2023-11-03

    This issue can be Closed.
    It was fixed upstream (commit).

     
    • Thomas Hurst

      Thomas Hurst - 2023-11-03

      The bundled version remains out of date.

       
      👍
      1

Log in to post a comment.