Skip to content

Commit 673a7e1

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 5c5ae1d commit 673a7e1

File tree

4 files changed

+26
-18
lines changed

4 files changed

+26
-18
lines changed

src/lib/openjp2/tcd.c

+17-13
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
685685
/* room needed to store l_nb_code_blocks code blocks for a precinct*/
686686
OPJ_UINT32 l_nb_code_blocks_size;
687687
/* size of data for a tile */
688-
OPJ_UINT32 l_data_size;
688+
size_t l_data_size;
689689

690690
l_cp = p_tcd->cp;
691691
l_tcp = &(l_cp->tcps[p_tile_no]);
@@ -726,18 +726,22 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
726726
/*fprintf(stderr, "\tTile compo border = %d,%d,%d,%d\n", l_tilec->x0, l_tilec->y0,l_tilec->x1,l_tilec->y1);*/
727727

728728
/* compute l_data_size with overflow check */
729-
l_data_size = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0);
730-
if ((((OPJ_UINT32)-1) / l_data_size) < (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0)) {
731-
opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
729+
l_data_size = l_tilec->x1 - l_tilec->x0;
730+
if (l_data_size == 0) {
731+
opj_event_msg(manager, EVT_ERROR, "Size of tile data is 0\n");
732+
return OPJ_FALSE;
733+
}
734+
else if ((SIZE_MAX / l_data_size) < (size_t)(l_tilec->y1 - l_tilec->y0)) {
735+
opj_event_msg(manager, EVT_ERROR, "Size of tile data exceeds system limits\n");
732736
return OPJ_FALSE;
733737
}
734-
l_data_size = l_data_size * (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0);
738+
l_data_size = l_data_size * (l_tilec->y1 - l_tilec->y0);
735739

736-
if ((((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(OPJ_UINT32)) < l_data_size) {
737-
opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n");
740+
if ((SIZE_MAX / sizeof(OPJ_UINT32)) < l_data_size) {
741+
opj_event_msg(manager, EVT_ERROR, "Size of tile data exceeds system limits\n");
738742
return OPJ_FALSE;
739743
}
740-
l_data_size = l_data_size * (OPJ_UINT32)sizeof(OPJ_UINT32);
744+
l_data_size = l_data_size * sizeof(OPJ_UINT32);
741745
l_tilec->numresolutions = l_tccp->numresolutions;
742746
if (l_tccp->numresolutions < l_cp->m_specific_param.m_dec.m_reduce) {
743747
l_tilec->minimum_num_resolutions = 1;
@@ -752,14 +756,14 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
752756
return OPJ_FALSE;
753757
}
754758

755-
l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof(opj_tcd_resolution_t);
759+
l_data_size = l_tilec->numresolutions * sizeof(opj_tcd_resolution_t);
756760

757761
if (l_tilec->resolutions == 00) {
758762
l_tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(l_data_size);
759763
if (! l_tilec->resolutions ) {
760764
return OPJ_FALSE;
761765
}
762-
/*fprintf(stderr, "\tAllocate resolutions of tilec (opj_tcd_resolution_t): %d\n",l_data_size);*/
766+
/*fprintf(stderr, "\tAllocate resolutions of tilec (opj_tcd_resolution_t): %tu\n", l_data_size);*/
763767
l_tilec->resolutions_size = l_data_size;
764768
memset(l_tilec->resolutions,0,l_data_size);
765769
}
@@ -773,7 +777,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
773777
return OPJ_FALSE;
774778
}
775779
l_tilec->resolutions = new_resolutions;
776-
/*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %d x OPJ_UINT32\n", l_tilec->resolutions_size, l_data_size);*/
780+
/*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %tu x OPJ_UINT32\n", l_tilec->resolutions_size, l_data_size);*/
777781
memset(((OPJ_BYTE*) l_tilec->resolutions)+l_tilec->resolutions_size,0,l_data_size - l_tilec->resolutions_size);
778782
l_tilec->resolutions_size = l_data_size;
779783
}
@@ -1069,9 +1073,9 @@ static OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_blo
10691073
*/
10701074
static OPJ_BOOL opj_tcd_code_block_enc_allocate_data (opj_tcd_cblk_enc_t * p_code_block)
10711075
{
1072-
OPJ_UINT32 l_data_size;
1076+
size_t l_data_size;
10731077

1074-
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));
1078+
l_data_size = (size_t)((p_code_block->x1 - p_code_block->x0) * (p_code_block->y1 - p_code_block->y0) * sizeof(OPJ_UINT32));
10751079

10761080
if (l_data_size > p_code_block->data_size) {
10771081
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
@@ -316,7 +316,10 @@ opj_decompress -i @INPUT_NR_PATH@/issue411-ycc420.jp2 -o @TEMP_PATH@/issue411-yc
316316
# issue 429 (from pdfium fuzz engine) 0 entries in PCLR box.
317317
!opj_decompress -i @INPUT_NR_PATH@/issue429.jp2 -o @TEMP_PATH@/issue429.jp2.pgx
318318
# issue 432 (from pdfium fuzz engine) Overflow in tcd tilec data size computation.
319-
!opj_decompress -i @INPUT_NR_PATH@/issue432.jp2 -o @TEMP_PATH@/issue432.jp2.pgx
319+
# On hosts with 64 bit size_t, opj_decompress now works.
320+
# On hosts with 32 bit size_t, opj_decompress cannot handle this file.
321+
# TODO: We need different test cases for both kinds of hosts. Don't run test until this works.
322+
## opj_decompress -i @INPUT_NR_PATH@/issue432.jp2 -o @TEMP_PATH@/issue432.jp2.pgx
320323
# issue 427 image width is 0
321324
!opj_decompress -i @INPUT_NR_PATH@/issue427-null-image-size.jp2 -o @TEMP_PATH@/issue427-null-image-size.jp2.pgx
322325
# issue 427 illegal tile offset

0 commit comments

Comments
 (0)