diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c index 14f6ff41a..d14e7013d 100644 --- a/src/lib/openjp2/j2k.c +++ b/src/lib/openjp2/j2k.c @@ -4695,7 +4695,7 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k, opj_tcp_t * l_tcp = 00; OPJ_UINT32 * l_tile_len = 00; OPJ_BOOL l_sot_length_pb_detected = OPJ_FALSE; - + int truncate = 0; /* preconditions */ assert(p_j2k != 00); assert(p_manager != 00); @@ -4728,9 +4728,10 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k, /* Check enough bytes left in stream before allocation */ if ((OPJ_OFF_T)p_j2k->m_specific_param.m_decoder.m_sot_length > opj_stream_get_number_byte_left(p_stream)) { - opj_event_msg(p_manager, EVT_ERROR, - "Tile part length size inconsistent with stream length\n"); - return OPJ_FALSE; + truncate = 1; + // opj_event_msg(p_manager, EVT_ERROR, + // "Tile part length size inconsistent with stream length\n"); + // return OPJ_FALSE; } if (p_j2k->m_specific_param.m_decoder.m_sot_length > UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA) { @@ -4746,8 +4747,15 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k, /* LH: oddly enough, in this path, l_tile_len!=0. * TODO: If this was consistent, we could simplify the code to only use realloc(), as realloc(0,...) default to malloc(0,...). */ - *l_current_data = (OPJ_BYTE*) opj_malloc( - p_j2k->m_specific_param.m_decoder.m_sot_length + OPJ_COMMON_CBLK_DATA_EXTRA); + if (!truncate) + { + *l_current_data = (OPJ_BYTE*) opj_malloc( + p_j2k->m_specific_param.m_decoder.m_sot_length + OPJ_COMMON_CBLK_DATA_EXTRA); + } + else + { + *l_current_data = (OPJ_BYTE*) opj_malloc(opj_stream_get_number_byte_left(p_stream) + OPJ_COMMON_CBLK_DATA_EXTRA); + } } else { OPJ_BYTE *l_new_current_data; if (*l_tile_len > UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA - @@ -4757,10 +4765,18 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k, "p_j2k->m_specific_param.m_decoder.m_sot_length"); return OPJ_FALSE; } - + if (!truncate) + { l_new_current_data = (OPJ_BYTE *) opj_realloc(*l_current_data, *l_tile_len + p_j2k->m_specific_param.m_decoder.m_sot_length + OPJ_COMMON_CBLK_DATA_EXTRA); + } + else + { + l_new_current_data = (OPJ_BYTE *) opj_realloc(*l_current_data, + *l_tile_len + opj_stream_get_number_byte_left(p_stream) + + OPJ_COMMON_CBLK_DATA_EXTRA); + } if (! l_new_current_data) { opj_free(*l_current_data); /*nothing more is done as l_current_data will be set to null, and just @@ -4804,7 +4820,7 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k, /*l_cstr_index->packno = 0;*/ } - + /* Patch to support new PHR data */ if (!l_sot_length_pb_detected) { l_current_read_size = opj_stream_read_data( @@ -4816,7 +4832,7 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k, l_current_read_size = 0; } - if (l_current_read_size != p_j2k->m_specific_param.m_decoder.m_sot_length) { + if ((l_current_read_size != p_j2k->m_specific_param.m_decoder.m_sot_length) || (truncate > 0) ) { p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC; } else { p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT; diff --git a/src/lib/openjp2/t2.c b/src/lib/openjp2/t2.c index 0887b9f5f..132d843fa 100644 --- a/src/lib/openjp2/t2.c +++ b/src/lib/openjp2/t2.c @@ -1305,6 +1305,7 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2, { OPJ_UINT32 bandno, cblkno; OPJ_UINT32 l_nb_code_blocks; + int truncate; OPJ_BYTE *l_current_data = p_src_data; opj_tcd_band_t *l_band = 00; opj_tcd_cblk_dec_t* l_cblk = 00; @@ -1313,6 +1314,7 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2, OPJ_ARG_NOT_USED(p_t2); OPJ_ARG_NOT_USED(pack_info); + l_band = l_res->bands; for (bandno = 0; bandno < l_res->numbands; ++bandno) { @@ -1346,18 +1348,26 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2, ++l_cblk->numsegs; } } - + truncate = 0; do { /* Check possible overflow (on l_current_data only, assumes input args already checked) then size */ - if ((((OPJ_SIZE_T)l_current_data + (OPJ_SIZE_T)l_seg->newlen) < - (OPJ_SIZE_T)l_current_data) || - (l_current_data + l_seg->newlen > p_src_data + p_max_length)) { - opj_event_msg(p_manager, EVT_ERROR, - "read: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n", - l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, - p_pi->compno); - return OPJ_FALSE; - } + if ((((OPJ_SIZE_T)l_current_data + (OPJ_SIZE_T)l_seg->newlen) < + (OPJ_SIZE_T)l_current_data) || + (l_current_data + l_seg->newlen > p_src_data + p_max_length)) { + + //opj_event_msg(p_manager, EVT_WARNING, + // "read: segment too long (%d) current data (%d) p_src_data (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n", + // l_seg->newlen, l_current_data, p_src_data, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, + // p_pi->compno); + truncate = 1; + l_seg->newlen = (OPJ_SIZE_T)(p_src_data + p_max_length - l_current_data); + + //opj_event_msg(p_manager, EVT_ERROR, + // "read: segment too long (%d) current data (%d) p_src_data (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n", + // l_seg->newlen, l_current_data, p_src_data, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, + // p_pi->compno); + //return OPJ_FALSE; + } #ifdef USE_JPWL /* we need here a j2k handle to verify if making a check to @@ -1409,7 +1419,7 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2, ++l_seg; ++l_cblk->numsegs; } - } while (l_cblk->numnewpasses > 0); + } while (l_cblk->numnewpasses > 0 && !truncate); l_cblk->real_num_segs = l_cblk->numsegs; ++l_cblk; @@ -1434,6 +1444,7 @@ static OPJ_BOOL opj_t2_skip_packet_data(opj_t2_t* p_t2, { OPJ_UINT32 bandno, cblkno; OPJ_UINT32 l_nb_code_blocks; + int truncate; opj_tcd_band_t *l_band = 00; opj_tcd_cblk_dec_t* l_cblk = 00; opj_tcd_resolution_t* l_res = @@ -1476,16 +1487,19 @@ static OPJ_BOOL opj_t2_skip_packet_data(opj_t2_t* p_t2, ++l_cblk->numsegs; } } - + truncate = 0; do { /* Check possible overflow then size */ if (((*p_data_read + l_seg->newlen) < (*p_data_read)) || ((*p_data_read + l_seg->newlen) > p_max_length)) { - opj_event_msg(p_manager, EVT_ERROR, - "skip: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n", - l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, - p_pi->compno); - return OPJ_FALSE; + //opj_event_msg(p_manager, EVT_ERROR, + // "skip: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n", + // l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, + // p_pi->compno); + truncate = 1; + l_seg->newlen = (OPJ_SIZE_T)(p_max_length - *p_data_read); + + // return OPJ_FALSE; } #ifdef USE_JPWL @@ -1518,7 +1532,7 @@ static OPJ_BOOL opj_t2_skip_packet_data(opj_t2_t* p_t2, ++l_seg; ++l_cblk->numsegs; } - } while (l_cblk->numnewpasses > 0); + } while (l_cblk->numnewpasses > 0 && !truncate); ++l_cblk; }