Skip to content

Commit

Permalink
Support files with very large data size
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
stweil committed Mar 25, 2016
1 parent 5c5ae1d commit a10fdc7
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 18 deletions.
26 changes: 13 additions & 13 deletions src/lib/openjp2/tcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions src/lib/openjp2/tcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
1 change: 1 addition & 0 deletions tests/nonregression/md5refs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions tests/nonregression/test_suite.ctest.in
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit a10fdc7

Please sign in to comment.