diff options
Diffstat (limited to 'jdhuff.c')
-rw-r--r-- | jdhuff.c | 30 |
1 files changed, 20 insertions, 10 deletions
@@ -540,6 +540,12 @@ process_restart(j_decompress_ptr cinfo) } +#if defined(__has_feature) +#if __has_feature(undefined_behavior_sanitizer) +__attribute__((no_sanitize("signed-integer-overflow"), + no_sanitize("unsigned-integer-overflow"))) +#endif +#endif LOCAL(boolean) decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) { @@ -572,11 +578,15 @@ decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) if (entropy->dc_needed[blkn]) { /* Convert DC difference to actual value, update last_dc_val */ int ci = cinfo->MCU_membership[blkn]; - /* This is really just - * s += state.last_dc_val[ci]; - * It is written this way in order to shut up UBSan. + /* Certain malformed JPEG images produce repeated DC coefficient + * differences of 2047 or -2047, which causes state.last_dc_val[ci] to + * grow until it overflows or underflows a 32-bit signed integer. This + * behavior is, to the best of our understanding, innocuous, and it is + * unclear how to work around it without potentially affecting + * performance. Thus, we (hopefully temporarily) suppress UBSan integer + * overflow errors for this function. */ - s = (int)((unsigned int)s + (unsigned int)state.last_dc_val[ci]); + s += state.last_dc_val[ci]; state.last_dc_val[ci] = s; if (block) { /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */ @@ -662,7 +672,7 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) d_derived_tbl *actbl = entropy->ac_cur_tbls[blkn]; register int s, k, r, l; - HUFF_DECODE_FAST(s, l, dctbl, slow_decode_mcu); + HUFF_DECODE_FAST(s, l, dctbl); if (s) { FILL_BIT_BUFFER_FAST r = GET_BITS(s); @@ -671,7 +681,7 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) if (entropy->dc_needed[blkn]) { int ci = cinfo->MCU_membership[blkn]; - s = (int)((unsigned int)s + (unsigned int)state.last_dc_val[ci]); + s += state.last_dc_val[ci]; state.last_dc_val[ci] = s; if (block) (*block)[0] = (JCOEF)s; @@ -680,7 +690,7 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) if (entropy->ac_needed[blkn] && block) { for (k = 1; k < DCTSIZE2; k++) { - HUFF_DECODE_FAST(s, l, actbl, slow_decode_mcu); + HUFF_DECODE_FAST(s, l, actbl); r = s >> 4; s &= 15; @@ -699,7 +709,7 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) } else { for (k = 1; k < DCTSIZE2; k++) { - HUFF_DECODE_FAST(s, l, actbl, slow_decode_mcu); + HUFF_DECODE_FAST(s, l, actbl); r = s >> 4; s &= 15; @@ -716,7 +726,6 @@ decode_mcu_fast(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) } if (cinfo->unread_marker != 0) { -slow_decode_mcu: cinfo->unread_marker = 0; return FALSE; } @@ -779,7 +788,8 @@ use_slow: } /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; + if (cinfo->restart_interval) + entropy->restarts_to_go--; return TRUE; } |