From da38bface6384cdd7f69733b08fb58e57a63cffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Tue, 21 Jul 2026 15:38:04 -0700 Subject: [PATCH] Fixed bounds check, and EXR channel pixel type. (#145) --- src/image.cpp | 25 +++++++++++++++++++++++-- src/image_decode.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/image.cpp b/src/image.cpp index a6a3406..71d8ae7 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -385,7 +385,7 @@ namespace bimg uint32_t mipHeight = bx::max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight); depth = bx::max(1, depth); - size += uint64_t(mipMidth/blockWidth * mipHeight/blockHeight * depth)*blockSize * sides; + size += uint64_t(mipMidth/blockWidth) * (mipHeight/blockHeight) * depth * blockSize * sides; width >>= 1; height >>= 1; @@ -6808,6 +6808,11 @@ namespace bimg if (_imageContainer.m_ktx) { + if (offset + sizeof(uint32_t) > uint64_t(_size) ) + { + return false; + } + const uint32_t size = _imageContainer.m_numLayers == 1 && _imageContainer.m_cubeMap ? mipSize : mipSize * numSides; uint32_t imageSize = *(const uint32_t*)&data[offset]; BX_ASSERT(size == imageSize, "KTX: Image size mismatch %d (expected %d).", size, imageSize); @@ -6823,6 +6828,11 @@ namespace bimg if (side == _side && lod == _lod) { + if (offset + mipSize > uint64_t(_size) ) + { + return false; + } + _mip.m_width = mipWidth; _mip.m_height = mipHeight; _mip.m_depth = depth; @@ -6877,12 +6887,18 @@ namespace bimg if (uint8_t(lod) == _lod) { + const uint64_t mipOffset = offset + uint64_t(_side) * mipSize; + if (mipOffset + mipSize > uint64_t(_size) ) + { + return false; + } + _mip.m_width = mipWidths [lod]; _mip.m_height = mipHeights[lod]; _mip.m_depth = mipDepths [lod]; _mip.m_blockSize = blockSize; _mip.m_size = mipSize; - _mip.m_data = &data[offset + _side * mipSize]; + _mip.m_data = &data[mipOffset]; _mip.m_bpp = bpp; _mip.m_format = format; _mip.m_hasAlpha = hasAlpha; @@ -6914,6 +6930,11 @@ namespace bimg if (side == _side && lod == _lod) { + if (offset + mipSize > uint64_t(_size) ) + { + return false; + } + _mip.m_width = mipWidth; _mip.m_height = mipHeight; _mip.m_depth = depth; diff --git a/src/image_decode.cpp b/src/image_decode.cpp index 31f20ff..99f26f1 100644 --- a/src/image_decode.cpp +++ b/src/image_decode.cpp @@ -593,6 +593,31 @@ namespace bimg result = ParseEXRHeaderFromMemory(&exrHeader, &exrVersion, (uint8_t*)_data, _size, &err); if (TINYEXR_SUCCESS == result) { + int uniformType = TINYEXR_PIXELTYPE_HALF; + for (int ii = 0; ii < exrHeader.num_channels; ++ii) + { + if (0 == bx::strCmp(exrHeader.channels[ii].name, "R") ) + { + uniformType = TINYEXR_PIXELTYPE_FLOAT == exrHeader.pixel_types[ii] + ? TINYEXR_PIXELTYPE_FLOAT + : TINYEXR_PIXELTYPE_HALF + ; + break; + } + } + + for (int ii = 0; ii < exrHeader.num_channels; ++ii) + { + const char* name = exrHeader.channels[ii].name; + if (0 == bx::strCmp(name, "R") + || 0 == bx::strCmp(name, "G") + || 0 == bx::strCmp(name, "B") + || 0 == bx::strCmp(name, "A") ) + { + exrHeader.requested_pixel_types[ii] = uniformType; + } + } + EXRImage exrImage; InitEXRImage(&exrImage);