Skip to content

Commit 24c4cab

Browse files
committed
Manually pull in fix for partial decodes from Jarrel Seah (uclouvain/openjpeg#1219)
1 parent 5709632 commit 24c4cab

File tree

2 files changed

+55
-26
lines changed

2 files changed

+55
-26
lines changed

src/lib/openjp2/j2k.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4711,7 +4711,7 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k,
47114711
opj_tcp_t * l_tcp = 00;
47124712
OPJ_UINT32 * l_tile_len = 00;
47134713
OPJ_BOOL l_sot_length_pb_detected = OPJ_FALSE;
4714-
4714+
int truncate = 0;
47154715
/* preconditions */
47164716
assert(p_j2k != 00);
47174717
assert(p_manager != 00);
@@ -4744,9 +4744,10 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k,
47444744
/* Check enough bytes left in stream before allocation */
47454745
if ((OPJ_OFF_T)p_j2k->m_specific_param.m_decoder.m_sot_length >
47464746
opj_stream_get_number_byte_left(p_stream)) {
4747-
opj_event_msg(p_manager, EVT_ERROR,
4748-
"Tile part length size inconsistent with stream length\n");
4749-
return OPJ_FALSE;
4747+
truncate = 1;
4748+
// opj_event_msg(p_manager, EVT_ERROR,
4749+
// "Tile part length size inconsistent with stream length\n");
4750+
// return OPJ_FALSE;
47504751
}
47514752
if (p_j2k->m_specific_param.m_decoder.m_sot_length >
47524753
UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA) {
@@ -4762,8 +4763,15 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k,
47624763
/* LH: oddly enough, in this path, l_tile_len!=0.
47634764
* TODO: If this was consistent, we could simplify the code to only use realloc(), as realloc(0,...) default to malloc(0,...).
47644765
*/
4765-
*l_current_data = (OPJ_BYTE*) opj_malloc(
4766-
p_j2k->m_specific_param.m_decoder.m_sot_length + OPJ_COMMON_CBLK_DATA_EXTRA);
4766+
if (!truncate)
4767+
{
4768+
*l_current_data = (OPJ_BYTE*) opj_malloc(
4769+
p_j2k->m_specific_param.m_decoder.m_sot_length + OPJ_COMMON_CBLK_DATA_EXTRA);
4770+
}
4771+
else
4772+
{
4773+
*l_current_data = (OPJ_BYTE*) opj_malloc(opj_stream_get_number_byte_left(p_stream) + OPJ_COMMON_CBLK_DATA_EXTRA);
4774+
}
47674775
} else {
47684776
OPJ_BYTE *l_new_current_data;
47694777
if (*l_tile_len > UINT_MAX - OPJ_COMMON_CBLK_DATA_EXTRA -
@@ -4773,10 +4781,18 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k,
47734781
"p_j2k->m_specific_param.m_decoder.m_sot_length");
47744782
return OPJ_FALSE;
47754783
}
4776-
4784+
if (!truncate)
4785+
{
47774786
l_new_current_data = (OPJ_BYTE *) opj_realloc(*l_current_data,
47784787
*l_tile_len + p_j2k->m_specific_param.m_decoder.m_sot_length +
47794788
OPJ_COMMON_CBLK_DATA_EXTRA);
4789+
}
4790+
else
4791+
{
4792+
l_new_current_data = (OPJ_BYTE *) opj_realloc(*l_current_data,
4793+
*l_tile_len + opj_stream_get_number_byte_left(p_stream) +
4794+
OPJ_COMMON_CBLK_DATA_EXTRA);
4795+
}
47804796
if (! l_new_current_data) {
47814797
opj_free(*l_current_data);
47824798
/*nothing more is done as l_current_data will be set to null, and just
@@ -4832,7 +4848,7 @@ static OPJ_BOOL opj_j2k_read_sod(opj_j2k_t *p_j2k,
48324848
l_current_read_size = 0;
48334849
}
48344850

4835-
if (l_current_read_size != p_j2k->m_specific_param.m_decoder.m_sot_length) {
4851+
if ((l_current_read_size != p_j2k->m_specific_param.m_decoder.m_sot_length) || (truncate > 0) ) {
48364852
p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC;
48374853
} else {
48384854
p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT;

src/lib/openjp2/t2.c

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,6 +1297,7 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
12971297
{
12981298
OPJ_UINT32 bandno, cblkno;
12991299
OPJ_UINT32 l_nb_code_blocks;
1300+
int truncate;
13001301
OPJ_BYTE *l_current_data = p_src_data;
13011302
opj_tcd_band_t *l_band = 00;
13021303
opj_tcd_cblk_dec_t* l_cblk = 00;
@@ -1338,18 +1339,26 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
13381339
++l_cblk->numsegs;
13391340
}
13401341
}
1341-
1342+
truncate = 0;
13421343
do {
13431344
/* Check possible overflow (on l_current_data only, assumes input args already checked) then size */
1344-
if ((((OPJ_SIZE_T)l_current_data + (OPJ_SIZE_T)l_seg->newlen) <
1345-
(OPJ_SIZE_T)l_current_data) ||
1346-
(l_current_data + l_seg->newlen > p_src_data + p_max_length)) {
1347-
opj_event_msg(p_manager, EVT_ERROR,
1348-
"read: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
1349-
l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno,
1350-
p_pi->compno);
1351-
return OPJ_FALSE;
1352-
}
1345+
if ((((OPJ_SIZE_T)l_current_data + (OPJ_SIZE_T)l_seg->newlen) <
1346+
(OPJ_SIZE_T)l_current_data) ||
1347+
(l_current_data + l_seg->newlen > p_src_data + p_max_length)) {
1348+
1349+
//opj_event_msg(p_manager, EVT_WARNING,
1350+
// "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",
1351+
// l_seg->newlen, l_current_data, p_src_data, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno,
1352+
// p_pi->compno);
1353+
truncate = 1;
1354+
l_seg->newlen = (OPJ_SIZE_T)(p_src_data + p_max_length - l_current_data);
1355+
1356+
//opj_event_msg(p_manager, EVT_ERROR,
1357+
// "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",
1358+
// l_seg->newlen, l_current_data, p_src_data, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno,
1359+
// p_pi->compno);
1360+
//return OPJ_FALSE;
1361+
}
13531362

13541363
#ifdef USE_JPWL
13551364
/* we need here a j2k handle to verify if making a check to
@@ -1401,7 +1410,7 @@ static OPJ_BOOL opj_t2_read_packet_data(opj_t2_t* p_t2,
14011410
++l_seg;
14021411
++l_cblk->numsegs;
14031412
}
1404-
} while (l_cblk->numnewpasses > 0);
1413+
} while (l_cblk->numnewpasses > 0 && !truncate);
14051414

14061415
l_cblk->real_num_segs = l_cblk->numsegs;
14071416
++l_cblk;
@@ -1426,6 +1435,7 @@ static OPJ_BOOL opj_t2_skip_packet_data(opj_t2_t* p_t2,
14261435
{
14271436
OPJ_UINT32 bandno, cblkno;
14281437
OPJ_UINT32 l_nb_code_blocks;
1438+
int truncate;
14291439
opj_tcd_band_t *l_band = 00;
14301440
opj_tcd_cblk_dec_t* l_cblk = 00;
14311441
opj_tcd_resolution_t* l_res =
@@ -1468,16 +1478,19 @@ static OPJ_BOOL opj_t2_skip_packet_data(opj_t2_t* p_t2,
14681478
++l_cblk->numsegs;
14691479
}
14701480
}
1471-
1481+
truncate = 0;
14721482
do {
14731483
/* Check possible overflow then size */
14741484
if (((*p_data_read + l_seg->newlen) < (*p_data_read)) ||
14751485
((*p_data_read + l_seg->newlen) > p_max_length)) {
1476-
opj_event_msg(p_manager, EVT_ERROR,
1477-
"skip: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
1478-
l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno,
1479-
p_pi->compno);
1480-
return OPJ_FALSE;
1486+
//opj_event_msg(p_manager, EVT_ERROR,
1487+
// "skip: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
1488+
// l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno,
1489+
// p_pi->compno);
1490+
truncate = 1;
1491+
l_seg->newlen = (OPJ_SIZE_T)(p_max_length - *p_data_read);
1492+
1493+
// return OPJ_FALSE;
14811494
}
14821495

14831496
#ifdef USE_JPWL
@@ -1510,7 +1523,7 @@ static OPJ_BOOL opj_t2_skip_packet_data(opj_t2_t* p_t2,
15101523
++l_seg;
15111524
++l_cblk->numsegs;
15121525
}
1513-
} while (l_cblk->numnewpasses > 0);
1526+
} while (l_cblk->numnewpasses > 0 && !truncate);
15141527

15151528
++l_cblk;
15161529
}

0 commit comments

Comments
 (0)