From 288ac60a383187112c2a583ac3087dd681ac1347 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Mon, 28 Mar 2016 11:15:43 +0200 Subject: [PATCH] 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 #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 #432 is disabled. Handle also a potential division by zero when l_data_size is 0. This fixes issue #733. Update also some comments in the test suite. Signed-off-by: Stefan Weil --- src/lib/openjp2/tcd.c | 23 +++++++++++------------ src/lib/openjp2/tcd.h | 4 ++-- tests/nonregression/md5refs.txt | 1 + tests/nonregression/test_suite.ctest.in | 9 ++++++--- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/lib/openjp2/tcd.c b/src/lib/openjp2/tcd.c index 631a48400..27b719a96 100644 --- a/src/lib/openjp2/tcd.c +++ b/src/lib/openjp2/tcd.c @@ -748,7 +748,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, /* room needed to store l_nb_code_blocks code blocks for a precinct*/ OPJ_UINT32 l_nb_code_blocks_size; /* size of data for a tile */ - OPJ_UINT32 l_data_size; + size_t l_data_size; l_cp = p_tcd->cp; l_tcp = &(l_cp->tcps[p_tile_no]); @@ -835,8 +835,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, l_tilec->data_size_needed = l_tile_data_size; } - l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof( - opj_tcd_resolution_t); + l_data_size = l_tilec->numresolutions * sizeof(opj_tcd_resolution_t); opj_image_data_free(l_tilec->data_win); l_tilec->data_win = NULL; @@ -850,7 +849,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, if (! l_tilec->resolutions) { return OPJ_FALSE; } - /*fprintf(stderr, "\tAllocate resolutions of tilec (opj_tcd_resolution_t): %d\n",l_data_size);*/ + /*fprintf(stderr, "\tAllocate resolutions of tilec (opj_tcd_resolution_t): %tu\n", l_data_size);*/ l_tilec->resolutions_size = l_data_size; memset(l_tilec->resolutions, 0, l_data_size); } else if (l_data_size > l_tilec->resolutions_size) { @@ -864,7 +863,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, return OPJ_FALSE; } l_tilec->resolutions = new_resolutions; - /*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %d x OPJ_UINT32\n", l_tilec->resolutions_size, l_data_size);*/ + /*fprintf(stderr, "\tReallocate data of tilec (int): from %d to %tu x OPJ_UINT32\n", l_tilec->resolutions_size, l_data_size);*/ memset(((OPJ_BYTE*) l_tilec->resolutions) + l_tilec->resolutions_size, 0, l_data_size - l_tilec->resolutions_size); l_tilec->resolutions_size = l_data_size; @@ -1206,14 +1205,14 @@ static OPJ_BOOL opj_tcd_code_block_enc_allocate(opj_tcd_cblk_enc_t * static OPJ_BOOL opj_tcd_code_block_enc_allocate_data(opj_tcd_cblk_enc_t * p_code_block) { - OPJ_UINT32 l_data_size; + size_t l_data_size; /* +1 is needed for https://github.com/uclouvain/openjpeg/issues/835 */ /* and actually +2 required for https://github.com/uclouvain/openjpeg/issues/982 */ /* TODO: is there a theoretical upper-bound for the compressed code */ /* block size ? */ - l_data_size = 2 + (OPJ_UINT32)((p_code_block->x1 - p_code_block->x0) * - (p_code_block->y1 - p_code_block->y0) * (OPJ_INT32)sizeof(OPJ_UINT32)); + l_data_size = 2 + ((size_t)(p_code_block->x1 - p_code_block->x0) * + (size_t)(p_code_block->y1 - p_code_block->y0) * sizeof(OPJ_UINT32)); if (l_data_size > p_code_block->data_size) { if (p_code_block->data) { @@ -1778,13 +1777,13 @@ OPJ_BOOL opj_tcd_update_tile_data(opj_tcd_t *p_tcd, static void opj_tcd_free_tile(opj_tcd_t *p_tcd) { - OPJ_UINT32 compno, resno, bandno, precno; + OPJ_UINT32 compno, bandno, precno; opj_tcd_tile_t *l_tile = 00; opj_tcd_tilecomp_t *l_tile_comp = 00; opj_tcd_resolution_t *l_res = 00; opj_tcd_band_t *l_band = 00; opj_tcd_precinct_t *l_precinct = 00; - OPJ_UINT32 l_nb_resolutions, l_nb_precincts; + OPJ_UINT32 l_nb_precincts; void (* l_tcd_code_block_deallocate)(opj_tcd_precinct_t *) = 00; if (! p_tcd) { @@ -1811,8 +1810,8 @@ static void opj_tcd_free_tile(opj_tcd_t *p_tcd) for (compno = 0; compno < l_tile->numcomps; ++compno) { l_res = l_tile_comp->resolutions; if (l_res) { - - l_nb_resolutions = l_tile_comp->resolutions_size / sizeof(opj_tcd_resolution_t); + size_t resno; + size_t l_nb_resolutions = l_tile_comp->resolutions_size / sizeof(opj_tcd_resolution_t); for (resno = 0; resno < l_nb_resolutions; ++resno) { l_band = l_res->bands; for (bandno = 0; bandno < 3; ++bandno) { diff --git a/src/lib/openjp2/tcd.h b/src/lib/openjp2/tcd.h index 63c22c457..a7ccaa652 100644 --- a/src/lib/openjp2/tcd.h +++ b/src/lib/openjp2/tcd.h @@ -82,7 +82,7 @@ typedef struct opj_tcd_cblk_enc { y1; /* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */ OPJ_UINT32 numbps; OPJ_UINT32 numlenbits; - OPJ_UINT32 data_size; /* Size of allocated data buffer */ + size_t data_size; /* Size of allocated data buffer */ OPJ_UINT32 numpasses; /* number of pass already done for the code-blocks */ OPJ_UINT32 numpassesinlayers; /* number of passes in the layer */ @@ -198,7 +198,7 @@ typedef struct opj_tcd_tilecomp { /* resolutions information */ opj_tcd_resolution_t *resolutions; /* size of data for resolutions (in bytes) */ - OPJ_UINT32 resolutions_size; + size_t resolutions_size; /* data of the component. For decoding, only valid if tcd->whole_tile_decoding is set (so exclusive of data_win member) */ OPJ_INT32 *data; diff --git a/tests/nonregression/md5refs.txt b/tests/nonregression/md5refs.txt index e95a10f08..cea7d2a1a 100644 --- a/tests/nonregression/md5refs.txt +++ b/tests/nonregression/md5refs.txt @@ -173,6 +173,7 @@ d5ecef537edf294af83826763c0cf860 issue411-ycc422.jp2_1.pgx 07480962d25b3d8cce18096648963c8a issue411-ycc420.jp2_0.pgx 149a69831b42401f20b8f7492ef99d97 issue411-ycc420.jp2_1.pgx ec8d1c99db9763a8ba489df4f41dda53 issue411-ycc420.jp2_2.pgx +895b5a311e96f458e3c058f2f50f4fa3 issue432.jp2_0.pgx 3c7ff2e4bdae849167be36589f32bcd5 issue458.jp2_0.pgx f004b48eafb2e52529cc9c7b6a3ff5d2 issue458.jp2_1.pgx 3127bd0a591d113c3c2428c8d2c14ec8 issue458.jp2_2.pgx diff --git a/tests/nonregression/test_suite.ctest.in b/tests/nonregression/test_suite.ctest.in index 718d05996..cf5460b8a 100644 --- a/tests/nonregression/test_suite.ctest.in +++ b/tests/nonregression/test_suite.ctest.in @@ -1,4 +1,4 @@ -# This file list all the input commands of the tests run by the ctest command which +# This file lists all the input commands of the tests run by the ctest command which # are not related to the conformance files. # # For each line of this file (except line which begin with #) an opj_compress test or a @@ -9,7 +9,7 @@ # + For decoder related tests = dump, compare dump to base, (TODO: compare outpout decoding # image to base) # -# Line begin with ! should failed (should be used for bad jpeg2000 file which should be +# Lines beginning with ! should fail (should be used for bad jpeg2000 file which should be # gracefully rejected). Please add a short resume about why this file should be rejected. # # You can use @INPUT_NR_PATH@ and @TEMP_PATH@ cmake variable which refers to OPJ_DATA_ROOT @@ -350,7 +350,10 @@ opj_decompress -i @INPUT_NR_PATH@/issue411-ycc420.jp2 -o @TEMP_PATH@/issue411-yc # issue 429 (from pdfium fuzz engine) 0 entries in PCLR box. !opj_decompress -i @INPUT_NR_PATH@/issue429.jp2 -o @TEMP_PATH@/issue429.jp2.pgx # issue 432 (from pdfium fuzz engine) Overflow in tcd tilec data size computation. -!opj_decompress -i @INPUT_NR_PATH@/issue432.jp2 -o @TEMP_PATH@/issue432.jp2.pgx +# On hosts with 64 bit size_t, opj_decompress now works. +# On hosts with 32 bit size_t, opj_decompress cannot handle this file. +# TODO: We need different test cases for both kinds of hosts. Don't run test until this works. +## opj_decompress -i @INPUT_NR_PATH@/issue432.jp2 -o @TEMP_PATH@/issue432.jp2.pgx # issue 427 image width is 0 !opj_decompress -i @INPUT_NR_PATH@/issue427-null-image-size.jp2 -o @TEMP_PATH@/issue427-null-image-size.jp2.pgx # issue 427 illegal tile offset