From a10fdc7eadb76e0c4cc11a4df89c7c11bf27916f Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Fri, 25 Mar 2016 10:54:51 +0100 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. Update also some comments in the test suite. Signed-off-by: Stefan Weil --- src/lib/openjp2/tcd.c | 26 ++++++++++++------------- src/lib/openjp2/tcd.h | 4 ++-- tests/nonregression/md5refs.txt | 1 + tests/nonregression/test_suite.ctest.in | 6 +++--- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/lib/openjp2/tcd.c b/src/lib/openjp2/tcd.c index 6eeb211e2..bc101c899 100644 --- a/src/lib/openjp2/tcd.c +++ b/src/lib/openjp2/tcd.c @@ -685,7 +685,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]); @@ -726,18 +726,18 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, /*fprintf(stderr, "\tTile compo border = %d,%d,%d,%d\n", l_tilec->x0, l_tilec->y0,l_tilec->x1,l_tilec->y1);*/ /* compute l_data_size with overflow check */ - l_data_size = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0); - if ((((OPJ_UINT32)-1) / l_data_size) < (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0)) { - opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n"); + l_data_size = l_tilec->x1 - l_tilec->x0; + if ((SIZE_MAX / l_data_size) < (size_t)(l_tilec->y1 - l_tilec->y0)) { + opj_event_msg(manager, EVT_ERROR, "Size of tile data exceeds system limits\n"); return OPJ_FALSE; } - l_data_size = l_data_size * (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0); + l_data_size = l_data_size * (l_tilec->y1 - l_tilec->y0); - if ((((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(OPJ_UINT32)) < l_data_size) { - opj_event_msg(manager, EVT_ERROR, "Not enough memory for tile data\n"); + if ((SIZE_MAX / sizeof(OPJ_UINT32)) < l_data_size) { + opj_event_msg(manager, EVT_ERROR, "Size of tile data exceeds system limits\n"); return OPJ_FALSE; } - l_data_size = l_data_size * (OPJ_UINT32)sizeof(OPJ_UINT32); + l_data_size = l_data_size * sizeof(OPJ_UINT32); l_tilec->numresolutions = l_tccp->numresolutions; if (l_tccp->numresolutions < l_cp->m_specific_param.m_dec.m_reduce) { l_tilec->minimum_num_resolutions = 1; @@ -752,14 +752,14 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no, return OPJ_FALSE; } - l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof(opj_tcd_resolution_t); + l_data_size = l_tilec->numresolutions * sizeof(opj_tcd_resolution_t); if (l_tilec->resolutions == 00) { l_tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(l_data_size); 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); } @@ -773,7 +773,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; } @@ -1069,9 +1069,9 @@ static OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_blo */ 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; - 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)); + l_data_size = (size_t)((p_code_block->x1 - p_code_block->x0) * (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) { diff --git a/src/lib/openjp2/tcd.h b/src/lib/openjp2/tcd.h index 07f8379af..4510d33c4 100644 --- a/src/lib/openjp2/tcd.h +++ b/src/lib/openjp2/tcd.h @@ -164,8 +164,8 @@ typedef struct opj_tcd_tilecomp OPJ_UINT32 resolutions_size; /* size of data for resolutions (in bytes) */ OPJ_INT32 *data; /* data of the component */ OPJ_BOOL ownsData; /* if true, then need to free after usage, otherwise do not free */ - OPJ_UINT32 data_size_needed; /* we may either need to allocate this amount of data, or re-use image data and ignore this value */ - OPJ_UINT32 data_size; /* size of the data of the component */ + size_t data_size_needed; /* we may either need to allocate this amount of data, or re-use image data and ignore this value */ + size_t data_size; /* size of the data of the component */ OPJ_INT32 numpix; /* add fixed_quality */ } opj_tcd_tilecomp_t; diff --git a/tests/nonregression/md5refs.txt b/tests/nonregression/md5refs.txt index 499441c03..f12045797 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 c316a5eae..d3e97e8d1 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 @@ -316,7 +316,7 @@ 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 +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