diff --git a/src/lib/OpenEXRCore/chunk.c b/src/lib/OpenEXRCore/chunk.c index 8d4edf5389..d92a8af4f3 100644 --- a/src/lib/OpenEXRCore/chunk.c +++ b/src/lib/OpenEXRCore/chunk.c @@ -71,16 +71,14 @@ extract_chunk_table ( ctxt, EXR_ERR_INVALID_ARGUMENT, "Invalid file with no chunks"); if (ctxt->file_size > 0 && - chunkbytes + chunkoff > (uint64_t) ctxt->file_size) - return ctxt->print_error ( - ctxt, - EXR_ERR_INVALID_ARGUMENT, - "chunk table size (%" PRIu64 - ") too big for file size (%" PRId64 ")", - chunkbytes, - ctxt->file_size); - - + chunkbytes + chunkoff > (uint64_t) ctxt->file_size) + return ctxt->print_error ( + ctxt, + EXR_ERR_INVALID_ARGUMENT, + "chunk table size (%" PRIu64 ") too big for file size (%" PRId64 + ")", + chunkbytes, + ctxt->file_size); ctable = (uint64_t*) ctxt->alloc_fn (chunkbytes); if (ctable == NULL) @@ -590,7 +588,8 @@ exr_read_tile_chunk_info ( int64_t fsize, tend, dend; const exr_attr_chlist_t* chanlist; const exr_attr_tiledesc_t* tiledesc; - int tilew, tileh, unpacksize = 0; + int tilew, tileh; + uint64_t texels, unpacksize = 0; uint64_t* ctable; EXR_PROMOTE_READ_CONST_CONTEXT_AND_PART_OR_ERROR (ctxt, part_index); @@ -656,11 +655,11 @@ exr_read_tile_chunk_info ( cinfo->level_y = (uint8_t) levely; chanlist = part->channels->chlist; + texels = (uint64_t) tilew * (uint64_t) tileh; for (int c = 0; c < chanlist->num_channels; ++c) { const exr_attr_chlist_entry_t* curc = (chanlist->entries + c); - unpacksize += - tilew * tileh * ((curc->pixel_type == EXR_PIXEL_HALF) ? 2 : 4); + unpacksize += texels * (uint64_t) ((curc->pixel_type == EXR_PIXEL_HALF) ? 2 : 4); } rv = extract_chunk_table (pctxt, part, &ctable); @@ -691,8 +690,8 @@ exr_read_tile_chunk_info ( return pctxt->print_error ( pctxt, rv, - "Request for tile (%d, %d), level (%d, %d) but unable to read %" PRId64 - " bytes from offset %" PRId64 ", got %" PRId64 " bytes", + "Unable to read information block for tile (%d, %d), level (%d, %d): request %" PRIu64 + " bytes from offset %" PRIu64 ", got %" PRIu64 " bytes", tilex, tiley, levelx, @@ -711,7 +710,7 @@ exr_read_tile_chunk_info ( return pctxt->print_error ( pctxt, EXR_ERR_BAD_CHUNK_LEADER, - "Preparing to read tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: part says %d, expected %d", + "Corrupt tile (%d, %d), level (%d, %d) (chunk %d): bad part number (%d, expect %d)", tilex, tiley, levelx, @@ -727,7 +726,7 @@ exr_read_tile_chunk_info ( return pctxt->print_error ( pctxt, EXR_ERR_BAD_CHUNK_LEADER, - "Preparing to read tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: found tile x %d, expect %d", + "Corrupt tile (%d, %d), level (%d, %d) (chunk %d): bad tile x coordinate (%d, expect %d)", tilex, tiley, levelx, @@ -741,7 +740,7 @@ exr_read_tile_chunk_info ( return pctxt->print_error ( pctxt, EXR_ERR_BAD_CHUNK_LEADER, - "Preparing to read tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: found tile y %d, expect %d", + "Corrupt tile (%d, %d), level (%d, %d) (chunk %d): bad tile Y coordinate (%d, expect %d)", tilex, tiley, levelx, @@ -755,7 +754,7 @@ exr_read_tile_chunk_info ( return pctxt->print_error ( pctxt, EXR_ERR_BAD_CHUNK_LEADER, - "Preparing to read tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: found tile level x %d, expect %d", + "Corrupt tile (%d, %d), level (%d, %d) (chunk %d): bad tile mip/rip level X (%d, expect %d)", tilex, tiley, levelx, @@ -769,7 +768,7 @@ exr_read_tile_chunk_info ( return pctxt->print_error ( pctxt, EXR_ERR_BAD_CHUNK_LEADER, - "Preparing to read tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: found tile level y %d, expect %d", + "Corrupt tile (%d, %d), level (%d, %d) (chunk %d): bad tile mip/rip level Y (%d, expect %d)", tilex, tiley, levelx, @@ -798,7 +797,7 @@ exr_read_tile_chunk_info ( return pctxt->print_error ( pctxt, EXR_ERR_BAD_CHUNK_LEADER, - "Preparing to read deep tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: invalid sample table size %" PRId64, + "Corrupt deep tile (%d, %d), level (%d, %d) (chunk %d): invalid sample table size %" PRId64, tilex, tiley, levelx, @@ -808,12 +807,12 @@ exr_read_tile_chunk_info ( } /* not all compressors support 64-bit */ - if (ddata[1] < 0 || ddata[1] > (int64_t) INT32_MAX) + if (ddata[1] <= 0 || ddata[1] > (int64_t) INT32_MAX) { return pctxt->print_error ( pctxt, EXR_ERR_BAD_CHUNK_LEADER, - "Preparing to read deep tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: invalid packed data size %" PRId64, + "Corrupt deep tile (%d, %d), level (%d, %d) (chunk %d): invalid packed data size %" PRId64, tilex, tiley, levelx, @@ -826,7 +825,7 @@ exr_read_tile_chunk_info ( return pctxt->print_error ( pctxt, EXR_ERR_BAD_CHUNK_LEADER, - "Preparing to read deep tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: invalid packed data size %" PRId64, + "Corrupt deep tile (%d, %d), level (%d, %d) (chunk %d): invalid unpacked size %" PRId64, tilex, tiley, levelx, @@ -848,7 +847,7 @@ exr_read_tile_chunk_info ( return pctxt->print_error ( pctxt, EXR_ERR_BAD_CHUNK_LEADER, - "Preparing to read deep tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: sample table and data result in access past end of the file: sample table size %" PRId64 + "Corrupt deep tile (%d, %d), level (%d, %d) (chunk %d): access past end of the file: sample table size %" PRId64 " + data size %" PRId64 " larger than file %" PRId64, tilex, tiley, @@ -862,25 +861,44 @@ exr_read_tile_chunk_info ( } else { - if (tdata[4] < 0 || tdata[4] > unpacksize || - (fsize > 0 && tdata[4] > fsize)) + if (tdata[4] <= 0 || ((uint64_t) tdata[4] > unpacksize)) { return pctxt->print_error ( pctxt, EXR_ERR_BAD_CHUNK_LEADER, - "Preparing to read deep tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: invalid packed size (%d) vs unpacked size (%d), and file size %" PRId64, + "Corrupt tile (%d, %d), level (%d, %d) (chunk %d): invalid packed size %d vs unpacked size %" PRIu64, tilex, tiley, levelx, levely, cidx, (int) tdata[4], - (int) unpacksize, - fsize); + unpacksize); } + else if (fsize > 0) + { + uint64_t finpos = dataoff + (uint64_t) tdata[4]; + if (finpos > fsize) + { + return pctxt->print_error ( + pctxt, + EXR_ERR_BAD_CHUNK_LEADER, + "Corrupt tile (%d, %d), level (%d, %d) (chunk %d): access past end of file: packed size (%d) at offset %" PRIu64 + " vs size of file %" PRId64, + tilex, + tiley, + levelx, + levely, + cidx, + (int) tdata[4], + dataoff, + fsize); + } + } + cinfo->packed_size = (uint64_t) tdata[4]; - cinfo->unpacked_size = (uint64_t) unpacksize; - cinfo->data_offset = (uint64_t) dataoff; + cinfo->unpacked_size = unpacksize; + cinfo->data_offset = dataoff; cinfo->sample_count_data_offset = 0; cinfo->sample_count_table_size = 0; }