From bbfacba0380a2683064cdc82aaa5a0dd869cc7c7 Mon Sep 17 00:00:00 2001 From: Kimball Thurston Date: Wed, 18 Sep 2024 08:44:01 +1200 Subject: [PATCH 1/2] Do nothing if there is nothing to do Add size checks against zero, zero samples could be a valid thing to encounter Signed-off-by: Kimball Thurston --- src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp | 6 ++++++ src/lib/OpenEXR/ImfDeepTiledInputFile.cpp | 6 ++++++ src/lib/OpenEXR/ImfScanLineInputFile.cpp | 3 +++ src/lib/OpenEXR/ImfTiledInputFile.cpp | 3 +++ src/lib/OpenEXRCore/compression.c | 4 +++- src/lib/OpenEXRCore/decoding.c | 9 ++++++--- 6 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp b/src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp index 31ec5ad667..e10cbd8694 100644 --- a/src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp +++ b/src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp @@ -931,6 +931,9 @@ void ScanLineProcess::run_fill ( int fbY, const std::vector &filllist) { + if (cinfo.height == 0 || cinfo.width == 0) + return; + for (auto& fills: filllist) { uint8_t* ptr; @@ -1011,6 +1014,9 @@ void ScanLineProcess::copy_sample_count ( { const Slice& scslice = outfb->getSampleCountSlice (); + if (cinfo.height == 0 || cinfo.width == 0) + return; + int end = cinfo.height - decoder.user_line_end_ignore; int64_t xS = int64_t (scslice.xStride); int64_t yS = int64_t (scslice.yStride); diff --git a/src/lib/OpenEXR/ImfDeepTiledInputFile.cpp b/src/lib/OpenEXR/ImfDeepTiledInputFile.cpp index 90de89ca75..d8b5069298 100644 --- a/src/lib/OpenEXR/ImfDeepTiledInputFile.cpp +++ b/src/lib/OpenEXR/ImfDeepTiledInputFile.cpp @@ -1141,6 +1141,9 @@ void TileProcess::run_fill ( const DeepFrameBuffer *outfb, int fb_absX, int fb_absY, int t_absX, int t_absY, const std::vector &filllist) { + if (cinfo.height == 0 || cinfo.width == 0) + return; + for (auto& fills: filllist) { uint8_t* ptr; @@ -1227,6 +1230,9 @@ void TileProcess::copy_sample_count ( if (s.xSampling != 1 || s.ySampling != 1) throw IEX_NAMESPACE::ArgExc ("Tiled data should not have subsampling."); + if (cinfo.height == 0 || cinfo.width == 0) + return; + int xOffset = s.xTileCoords ? 0 : t_absX; int yOffset = s.yTileCoords ? 0 : t_absY; diff --git a/src/lib/OpenEXR/ImfScanLineInputFile.cpp b/src/lib/OpenEXR/ImfScanLineInputFile.cpp index f7eb144701..415d7c798a 100644 --- a/src/lib/OpenEXR/ImfScanLineInputFile.cpp +++ b/src/lib/OpenEXR/ImfScanLineInputFile.cpp @@ -660,6 +660,9 @@ void ScanLineProcess::run_fill ( int fbY, const std::vector &filllist) { + if (cinfo.height == 0 || cinfo.width == 0) + return; + for (auto& s: filllist) { uint8_t* ptr; diff --git a/src/lib/OpenEXR/ImfTiledInputFile.cpp b/src/lib/OpenEXR/ImfTiledInputFile.cpp index d37115312d..6dce225ae7 100644 --- a/src/lib/OpenEXR/ImfTiledInputFile.cpp +++ b/src/lib/OpenEXR/ImfTiledInputFile.cpp @@ -988,6 +988,9 @@ void TileProcess::run_fill ( const FrameBuffer *outfb, int fb_absX, int fb_absY, int t_absX, int t_absY, const std::vector &filllist) { + if (cinfo.height == 0 || cinfo.width == 0) + return; + for (auto& s: filllist) { uint8_t* ptr; diff --git a/src/lib/OpenEXRCore/compression.c b/src/lib/OpenEXRCore/compression.c index ea7c9ff2af..9271e1daa9 100644 --- a/src/lib/OpenEXRCore/compression.c +++ b/src/lib/OpenEXRCore/compression.c @@ -509,7 +509,9 @@ exr_uncompress_chunk (exr_decode_pipeline_t* decode) if ((decode->decode_flags & EXR_DECODE_SAMPLE_DATA_ONLY)) return rv; } - if (rv == EXR_ERR_SUCCESS) + if (rv == EXR_ERR_SUCCESS && + decode->chunk.packed_size > 0 && + decode->chunk.unpacked_size > 0) rv = decompress_data ( ctxt, part->comp_type, diff --git a/src/lib/OpenEXRCore/decoding.c b/src/lib/OpenEXRCore/decoding.c index 1db0ba90fc..4e24040236 100644 --- a/src/lib/OpenEXRCore/decoding.c +++ b/src/lib/OpenEXRCore/decoding.c @@ -154,8 +154,9 @@ default_read_chunk (exr_decode_pipeline_t* decode) decode->unpacked_alloc_size == 0) decode->unpacked_buffer = NULL; - if (part->storage_mode == EXR_STORAGE_DEEP_SCANLINE || - part->storage_mode == EXR_STORAGE_DEEP_TILED) + if ((part->storage_mode == EXR_STORAGE_DEEP_SCANLINE || + part->storage_mode == EXR_STORAGE_DEEP_TILED) && + decode->chunk.sample_count_table_size > 0) { rv = internal_decode_alloc_buffer ( decode, @@ -192,7 +193,7 @@ default_read_chunk (exr_decode_pipeline_t* decode) decode->packed_sample_count_table); } } - else + else if (decode->chunk.packed_size > 0) { rv = internal_decode_alloc_buffer ( decode, @@ -204,6 +205,8 @@ default_read_chunk (exr_decode_pipeline_t* decode) rv = exr_read_chunk ( ctxt, decode->part_index, &(decode->chunk), decode->packed_buffer); } + else + rv = EXR_ERR_SUCCESS; return rv; } From bbab8d1a3f67725d6553ee2abdf23c44e161c95c Mon Sep 17 00:00:00 2001 From: Kimball Thurston Date: Wed, 18 Sep 2024 08:44:36 +1200 Subject: [PATCH 2/2] add extra safety check during decode for bad file header should only trigger if someone doesn't check return values Signed-off-by: Kimball Thurston --- src/lib/OpenEXRCore/decoding.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib/OpenEXRCore/decoding.c b/src/lib/OpenEXRCore/decoding.c index 4e24040236..a4044b9742 100644 --- a/src/lib/OpenEXRCore/decoding.c +++ b/src/lib/OpenEXRCore/decoding.c @@ -313,6 +313,11 @@ exr_decoding_initialize ( } } + // will have already been reported during header parse, but just + // stop the file from being read + if (!part->channels || part->channels->type != EXR_ATTR_CHLIST) + return EXR_ERR_INVALID_ATTR; + rv = internal_coding_fill_channel_info ( &(decode->channels), &(decode->channel_count),