diff --git a/src/bin/exrmetrics/exrmetrics.cpp b/src/bin/exrmetrics/exrmetrics.cpp index 46c19a7ba..776ae22f4 100644 --- a/src/bin/exrmetrics/exrmetrics.cpp +++ b/src/bin/exrmetrics/exrmetrics.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -46,6 +47,25 @@ using std::vector; using std::chrono::steady_clock; using std::isinf; +namespace { + +// +// Validate that count*sampleSize casts to size_t without overflow, before +// using the value to resize a std::vector. +// + +size_t +vectorSize (uint64_t count, int sampleSize = 1) +{ + const uint64_t sampleSizeU = static_cast (sampleSize); + const uint64_t maxSize = std::numeric_limits::max (); + if (sampleSizeU > 0 && count > maxSize / sampleSizeU) + throw IEX_NAMESPACE::OverflowExc ("Integer multiplication overflow."); + return static_cast (count * sampleSizeU); +} + +} // namespace + double timing (steady_clock::time_point start, steady_clock::time_point end) { @@ -92,7 +112,7 @@ initScanLine ( size_t pixelsInChannel = (width / i.channel ().xSampling) * (height / i.channel ().ySampling); rawSize += pixelsInChannel * samplesize; - pixelData[channelNumber].resize (numPixels * samplesize); + pixelData[channelNumber].resize (vectorSize (numPixels, samplesize)); buf.insert ( i.name (), @@ -205,7 +225,7 @@ initTiled ( { int samplesize = pixelTypeSize (i.channel ().type); pixelData[levelIndex][channelNumber].resize ( - numPixels * samplesize); + vectorSize (numPixels, samplesize)); buf[levelIndex].insert ( i.name (), @@ -324,7 +344,7 @@ initAndReadDeepScanLine ( uint64_t height = dw.max.y + 1 - dw.min.y; uint64_t numPixels = width * height; int numChans = channelCount (in.header ()); - sampleCount.resize (numPixels); + sampleCount.resize (vectorSize (numPixels)); uint64_t offsetToOrigin = width * static_cast (dw.min.y) + static_cast (dw.min.x); @@ -342,7 +362,7 @@ initAndReadDeepScanLine ( i != outHeader.channels ().end (); ++i) { - pixelPtrs[channelNumber].resize (numPixels); + pixelPtrs[channelNumber].resize (vectorSize (numPixels)); int samplesize = pixelTypeSize (i.channel ().type); buf.insert ( i.name (), @@ -492,7 +512,7 @@ initAndReadDeepTiled ( static_cast (dw.min.x); pixelPtrs.resize (numChans); - sampleCount.resize (numPixels); + sampleCount.resize (vectorSize (numPixels)); buf.insertSampleCountSlice (Slice ( UINT, @@ -506,7 +526,7 @@ initAndReadDeepTiled ( i != outHeader.channels ().end (); ++i) { - pixelPtrs[channelNumber].resize (numPixels); + pixelPtrs[channelNumber].resize (vectorSize (numPixels)); int samplesize = pixelTypeSize (i.channel ().type); buf.insert ( i.name (),