google / wuffs

Wrangling Untrusted File Formats Safely
Other
4.06k stars 129 forks source link

"bad huffman code under subscribed" error on valid PNG #66

Closed richgel999 closed 2 years ago

richgel999 commented 2 years ago

Hi, I'm unable to load a valid PNG (see attached file) using wuffs, but this PNG loads with libpng (zlib), stb_image.h, lodepng, and validates OK with pngcheck. After some investigation it appears that if the Deflate distance table only has a single used code (with a bit length of 1), wuffs refuses to load the image.

This is incorrect behavior, as far as I can tell. From the Deflate spec 3.2.7. Compression with dynamic Huffman codes (BTYPE=10):

https://datatracker.ietf.org/doc/rfc1951/

If only one distance code is used, it is encoded using one bit, not zero bits; 
in this case there is a single code length of one, with one unused code. 

The problem is in function wuffs_deflatedecoderinit_huff():

if (v_remaining != 0) {
    if ((a_which == 1) &&
        (v_counts[1] == 1) &&
        (self->private_data.f_code_lengths[a_n_codes0] == 1) &&
        ((((uint32_t)(v_counts[0])) + a_n_codes0 + 1) == a_n_codes1)) {
      self->private_impl.f_n_huffs_bits[1] = 1;
      self->private_data.f_huffs[1][0] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[0] | 1);
      self->private_data.f_huffs[1][1] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[31] | 1);
      return wuffs_base__make_status(NULL);
    }
    return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_under_subscribed);
  }

bad_huffman_code_under_subscribed_error

nigeltao commented 2 years ago

Thanks for the great bug report.

release/c/wuffs-v0.3.c picked up the fix in the follow-up commit 58608c4e.

https://github.com/richgel999/fpng is also a cool project. :-)