Skip to content

Commit 2d62cd6

Browse files
committed
Support files with very large data size
The maximum supported data size is a limiting factor for the maximum size of allowed images. As it is possible to allocate size_t bytes, this data type must also be used for the data size. This modification also fixes issue uclouvain#432. That file is now decoded on 64 bit hosts with enough RAM, so the regression test had to be fixed. Until it is possible to use different test cases for 32 and 64 bit hosts, the test for issue uclouvain#432 is disabled. Handle also a potential division by zero when l_data_size is 0. This fixes issue uclouvain#733. Update also some comments in the test suite. Signed-off-by: Stefan Weil <sw@weilnetz.de>
1 parent 162f619 commit 2d62cd6

File tree

4 files changed

+21
-17
lines changed

4 files changed

+21
-17
lines changed

src/lib/openjp2/tcd.c

+12-12
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
678678
/* room needed to store l_nb_code_blocks code blocks for a precinct*/
679679
OPJ_UINT32 l_nb_code_blocks_size;
680680
/* size of data for a tile */
681-
OPJ_UINT32 l_data_size;
681+
size_t l_data_size;
682682

683683
l_cp = p_tcd->cp;
684684
l_tcp = &(l_cp->tcps[p_tile_no]);
@@ -719,19 +719,19 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
719719
/*fprintf(stderr, "\tTile compo border = %d,%d,%d,%d\n", l_tilec->x0, l_tilec->y0,l_tilec->x1,l_tilec->y1);*/
720720

721721
/* compute l_data_size with overflow check */
722-
l_data_size = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0);
722+
l_data_size = l_tilec->x1 - l_tilec->x0;
723723
/* issue 733, l_data_size == 0U, probably something wrong should be checked before getting here */
724-
if ((l_data_size > 0U) && ((((OPJ_UINT32)-1) / l_data_size) < (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0))) {
724+
if ((l_data_size > 0U) && ((SIZE_MAX / l_data_size) < (size_t)(l_tilec->y1 - l_tilec->y0))) {
725725
opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
726726
return OPJ_FALSE;
727727
}
728-
l_data_size = l_data_size * (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0);
728+
l_data_size = l_data_size * (l_tilec->y1 - l_tilec->y0);
729729

730-
if ((((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(OPJ_UINT32)) < l_data_size) {
731-
opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
730+
if ((SIZE_MAX / sizeof(OPJ_UINT32)) < l_data_size) {
731+
opj_event_msg(manager, EVT_ERROR, "Size of tile data exceeds system limits\n");
732732
return OPJ_FALSE;
733733
}
734-
l_data_size = l_data_size * (OPJ_UINT32)sizeof(OPJ_UINT32);
734+
l_data_size = l_data_size * sizeof(OPJ_UINT32);
735735
l_tilec->numresolutions = l_tccp->numresolutions;
736736
if (l_tccp->numresolutions < l_cp->m_specific_param.m_dec.m_reduce) {
737737
l_tilec->minimum_num_resolutions = 1;
@@ -746,14 +746,14 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
746746
return OPJ_FALSE;
747747
}
748748

749-
l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof(opj_tcd_resolution_t);
749+
l_data_size = l_tilec->numresolutions * sizeof(opj_tcd_resolution_t);
750750

751751
if (l_tilec->resolutions == 00) {
752752
l_tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(l_data_size);
753753
if (! l_tilec->resolutions ) {
754754
return OPJ_FALSE;
755755
}
756-
/*fprintf(stderr, "\tAllocate resolutions of tilec (opj_tcd_resolution_t): %d\n",l_data_size);*/
756+
/*fprintf(stderr, "\tAllocate resolutions of tilec (opj_tcd_resolution_t): %tu\n", l_data_size);*/
757757
l_tilec->resolutions_size = l_data_size;
758758
memset(l_tilec->resolutions,0,l_data_size);
759759
}
@@ -767,7 +767,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
767767
return OPJ_FALSE;
768768
}
769769
l_tilec->resolutions = new_resolutions;
770-
/*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %d x OPJ_UINT32\n", l_tilec->resolutions_size, l_data_size);*/
770+
/*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %tu x OPJ_UINT32\n", l_tilec->resolutions_size, l_data_size);*/
771771
memset(((OPJ_BYTE*) l_tilec->resolutions)+l_tilec->resolutions_size,0,l_data_size - l_tilec->resolutions_size);
772772
l_tilec->resolutions_size = l_data_size;
773773
}
@@ -1064,9 +1064,9 @@ static OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_blo
10641064
*/
10651065
static OPJ_BOOL opj_tcd_code_block_enc_allocate_data (opj_tcd_cblk_enc_t * p_code_block)
10661066
{
1067-
OPJ_UINT32 l_data_size;
1067+
size_t l_data_size;
10681068

1069-
l_data_size = (OPJ_UINT32)((p_code_block->x1 - p_code_block->x0) * (p_code_block->y1 - p_code_block->y0) * (OPJ_INT32)sizeof(OPJ_UINT32));
1069+
l_data_size = (size_t)((p_code_block->x1 - p_code_block->x0) * (p_code_block->y1 - p_code_block->y0) * sizeof(OPJ_UINT32));
10701070

10711071
if (l_data_size > p_code_block->data_size) {
10721072
if (p_code_block->data) {

src/lib/openjp2/tcd.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ typedef struct opj_tcd_tilecomp
164164
OPJ_UINT32 resolutions_size; /* size of data for resolutions (in bytes) */
165165
OPJ_INT32 *data; /* data of the component */
166166
OPJ_BOOL ownsData; /* if true, then need to free after usage, otherwise do not free */
167-
OPJ_UINT32 data_size_needed; /* we may either need to allocate this amount of data, or re-use image data and ignore this value */
168-
OPJ_UINT32 data_size; /* size of the data of the component */
167+
size_t data_size_needed; /* we may either need to allocate this amount of data, or re-use image data and ignore this value */
168+
size_t data_size; /* size of the data of the component */
169169
OPJ_INT32 numpix; /* add fixed_quality */
170170
} opj_tcd_tilecomp_t;
171171

tests/nonregression/md5refs.txt

+1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ d5ecef537edf294af83826763c0cf860 issue411-ycc422.jp2_1.pgx
173173
07480962d25b3d8cce18096648963c8a issue411-ycc420.jp2_0.pgx
174174
149a69831b42401f20b8f7492ef99d97 issue411-ycc420.jp2_1.pgx
175175
ec8d1c99db9763a8ba489df4f41dda53 issue411-ycc420.jp2_2.pgx
176+
895b5a311e96f458e3c058f2f50f4fa3 issue432.jp2_0.pgx
176177
3c7ff2e4bdae849167be36589f32bcd5 issue458.jp2_0.pgx
177178
f004b48eafb2e52529cc9c7b6a3ff5d2 issue458.jp2_1.pgx
178179
3127bd0a591d113c3c2428c8d2c14ec8 issue458.jp2_2.pgx

tests/nonregression/test_suite.ctest.in

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# This file list all the input commands of the tests run by the ctest command which
1+
# This file lists all the input commands of the tests run by the ctest command which
22
# are not related to the conformance files.
33
#
44
# For each line of this file (except line which begin with #) an opj_compress test or a
@@ -9,7 +9,7 @@
99
# + For decoder related tests = dump, compare dump to base, (TODO: compare outpout decoding
1010
# image to base)
1111
#
12-
# Line begin with ! should failed (should be used for bad jpeg2000 file which should be
12+
# Lines beginning with ! should fail (should be used for bad jpeg2000 file which should be
1313
# gracefully rejected). Please add a short resume about why this file should be rejected.
1414
#
1515
# You can use @INPUT_NR_PATH@ and @TEMP_PATH@ cmake variable which refers to OPJ_DATA_ROOT
@@ -326,7 +326,10 @@ opj_decompress -i @INPUT_NR_PATH@/issue411-ycc420.jp2 -o @TEMP_PATH@/issue411-yc
326326
# issue 429 (from pdfium fuzz engine) 0 entries in PCLR box.
327327
!opj_decompress -i @INPUT_NR_PATH@/issue429.jp2 -o @TEMP_PATH@/issue429.jp2.pgx
328328
# issue 432 (from pdfium fuzz engine) Overflow in tcd tilec data size computation.
329-
!opj_decompress -i @INPUT_NR_PATH@/issue432.jp2 -o @TEMP_PATH@/issue432.jp2.pgx
329+
# On hosts with 64 bit size_t, opj_decompress now works.
330+
# On hosts with 32 bit size_t, opj_decompress cannot handle this file.
331+
# TODO: We need different test cases for both kinds of hosts. Don't run test until this works.
332+
## opj_decompress -i @INPUT_NR_PATH@/issue432.jp2 -o @TEMP_PATH@/issue432.jp2.pgx
330333
# issue 427 image width is 0
331334
!opj_decompress -i @INPUT_NR_PATH@/issue427-null-image-size.jp2 -o @TEMP_PATH@/issue427-null-image-size.jp2.pgx
332335
# issue 427 illegal tile offset

0 commit comments

Comments
 (0)