File openexr-CVE-2020-11762,11758,11764,11765,11763,11761,11760.patch of Package openexr.20697
Index: openexr-2.2.1/IlmImf/ImfCompositeDeepScanLine.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImf/ImfCompositeDeepScanLine.cpp 2017-11-18 00:00:24.000000000 +0100
+++ openexr-2.2.1/IlmImf/ImfCompositeDeepScanLine.cpp 2020-04-20 13:12:55.771430664 +0200
@@ -44,6 +44,7 @@
#include <Iex.h>
#include <vector>
+#include <stddef.h>
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
using std::vector;
@@ -179,7 +180,7 @@ CompositeDeepScanLine::Data::handleDeepF
int start,
int end)
{
- int width=_dataWindow.size().x+1;
+ ptrdiff_t width=_dataWindow.size().x+1;
size_t pixelcount = width * (end-start+1);
pointers.resize(_channels.size());
counts.resize(pixelcount);
Index: openexr-2.2.1/IlmImf/ImfDeepScanLineInputFile.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImf/ImfDeepScanLineInputFile.cpp 2017-11-18 00:00:24.000000000 +0100
+++ openexr-2.2.1/IlmImf/ImfDeepScanLineInputFile.cpp 2020-04-20 14:35:32.472988601 +0200
@@ -915,8 +915,7 @@ void DeepScanLineInputFile::initialize(c
}
catch (...)
{
- delete _data;
- _data=NULL;
+ // Don't delete _data here, leave that to caller
throw;
}
}
@@ -932,8 +931,15 @@ DeepScanLineInputFile::DeepScanLineInput
_data->memoryMapped = _data->_streamData->is->isMemoryMapped();
_data->version = part->version;
- initialize(part->header);
-
+ try
+ {
+ initialize(part->header);
+ }
+ catch(...)
+ {
+ delete _data;
+ throw;
+ }
_data->lineOffsets = part->chunkOffsets;
_data->partNumber = part->partNumber;
@@ -945,7 +951,6 @@ DeepScanLineInputFile::DeepScanLineInput
:
_data (new Data (numThreads))
{
- _data->_streamData = new InputStreamMutex();
_data->_deleteStream = true;
OPENEXR_IMF_INTERNAL_NAMESPACE::IStream* is = 0;
@@ -955,12 +960,29 @@ DeepScanLineInputFile::DeepScanLineInput
readMagicNumberAndVersionField(*is, _data->version);
//
// Backward compatibility to read multpart file.
- //
+ // multiPartInitialize will create _streamData
if (isMultiPart(_data->version))
{
compatibilityInitialize(*is);
return;
}
+ }
+ catch (IEX_NAMESPACE::BaseExc &e)
+ {
+ if (is) delete is;
+ if (_data) delete _data;
+
+ REPLACE_EXC (e, "Cannot read image file "
+ "\"" << fileName << "\". " << e.what());
+ throw;
+ }
+
+ //
+ // not multiPart - allocate stream data and intialise as normal
+ //
+ try
+ {
+ _data->_streamData = new InputStreamMutex();
_data->_streamData->is = is;
_data->memoryMapped = is->isMemoryMapped();
_data->header.readFrom (*_data->_streamData->is, _data->version);
@@ -976,7 +998,10 @@ DeepScanLineInputFile::DeepScanLineInput
catch (IEX_NAMESPACE::BaseExc &e)
{
if (is) delete is;
- if (_data && _data->_streamData) delete _data->_streamData;
+ if (_data && _data->_streamData)
+ {
+ delete _data->_streamData;
+ }
if (_data) delete _data;
REPLACE_EXC (e, "Cannot read image file "
@@ -986,7 +1011,10 @@ DeepScanLineInputFile::DeepScanLineInput
catch (...)
{
if (is) delete is;
- if (_data && _data->_streamData) delete _data->_streamData;
+ if (_data && _data->_streamData)
+ {
+ delete _data->_streamData;
+ }
if (_data) delete _data;
throw;
@@ -1010,7 +1038,18 @@ DeepScanLineInputFile::DeepScanLineInput
_data->version =version;
- initialize (header);
+ try
+ {
+ initialize (header);
+ }
+ catch (...)
+ {
+ if (_data && _data->_streamData)
+ {
+ delete _data->_streamData;
+ }
+ if (_data) delete _data;
+ }
readLineOffsets (*_data->_streamData->is,
_data->lineOrder,
@@ -1042,8 +1081,9 @@ DeepScanLineInputFile::~DeepScanLineInpu
//
if (_data->partNumber == -1 && _data->_streamData)
+ {
delete _data->_streamData;
-
+ }
delete _data;
}
}
Index: openexr-2.2.1/IlmImf/ImfDeepTiledInputFile.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImf/ImfDeepTiledInputFile.cpp 2017-11-18 00:00:24.000000000 +0100
+++ openexr-2.2.1/IlmImf/ImfDeepTiledInputFile.cpp 2020-04-20 13:12:55.771430664 +0200
@@ -283,7 +283,8 @@ DeepTiledInputFile::Data::Data (int numT
multiPartBackwardSupport(false),
numThreads(numThreads),
memoryMapped(false),
- _streamData(NULL),
+ sampleCountTableComp(nullptr),
+ _streamData(nullptr),
_deleteStream(false)
{
//
@@ -308,6 +309,8 @@ DeepTiledInputFile::Data::~Data ()
for (size_t i = 0; i < slices.size(); i++)
delete slices[i];
+
+ delete sampleCountTableComp;
}
@@ -927,7 +930,15 @@ DeepTiledInputFile::DeepTiledInputFile (
_data (new Data (part->numThreads))
{
_data->_deleteStream=false;
- multiPartInitialize(part);
+ try
+ {
+ multiPartInitialize(part);
+ }
+ catch(...)
+ {
+ delete _data;
+ throw;
+ }
}
Index: openexr-2.2.1/IlmImf/ImfDwaCompressor.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImf/ImfDwaCompressor.cpp 2017-11-18 00:00:24.000000000 +0100
+++ openexr-2.2.1/IlmImf/ImfDwaCompressor.cpp 2020-04-20 14:35:32.472988601 +0200
@@ -265,8 +265,9 @@ struct DwaCompressor::Classifier
" (truncated rule).");
{
- char suffix[Name::SIZE];
- memset (suffix, 0, Name::SIZE);
+ // maximum length of string plus one byte for terminating NULL
+ char suffix[Name::SIZE+1];
+ memset (suffix, 0, Name::SIZE+1);
Xdr::read<CharPtrIO> (ptr, std::min(size, Name::SIZE-1), suffix);
_suffix = std::string(suffix);
}
@@ -2409,7 +2410,7 @@ DwaCompressor::uncompress
unsigned short ruleSize = 0;
Xdr::read<CharPtrIO>(dataPtr, ruleSize);
- if (ruleSize < 0)
+ if (ruleSize < Xdr::size<unsigned short>())
throw Iex::InputExc("Error uncompressing DWA data"
" (corrupt header file).");
@@ -2806,6 +2807,14 @@ DwaCompressor::uncompress
if (Imath::modp (y, cd->ySampling) != 0)
continue;
+ //
+ // sanity check for buffer data lying within range
+ //
+ if (cd->planarUncBufferEnd + dstScanlineSize - _planarUncBuffer[UNKNOWN] > _planarUncBufferSize[UNKNOWN] )
+ {
+ throw Iex::InputExc("DWA data corrupt");
+ }
+
memcpy (rowPtrs[chan][row],
cd->planarUncBufferEnd,
dstScanlineSize);
Index: openexr-2.2.1/IlmImf/ImfFastHuf.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImf/ImfFastHuf.cpp 2020-04-20 13:12:55.775430685 +0200
+++ openexr-2.2.1/IlmImf/ImfFastHuf.cpp 2020-04-20 13:32:47.229614784 +0200
@@ -256,14 +256,29 @@ FastHufDecoder::FastHufDecoder
int symbol = *i >> 6;
if (mapping[codeLen] >= _numSymbols)
+ {
+ delete[] _idToSymbol;
+ _idToSymbol = NULL;
throw Iex::InputExc ("Huffman decode error "
"(Invalid symbol in header).");
-
+ }
_idToSymbol[mapping[codeLen]] = symbol;
mapping[codeLen]++;
}
- buildTables(base, offset);
+ //
+ // exceptions can be thrown whilst building tables. Delete
+ // _idToSynmbol before re-throwing to prevent memory leak
+ //
+ try
+ {
+ buildTables(base, offset);
+ }catch(...)
+ {
+ delete[] _idToSymbol;
+ _idToSymbol = NULL;
+ throw;
+ }
}
Index: openexr-2.2.1/IlmImf/ImfHeader.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImf/ImfHeader.cpp 2020-04-20 13:12:55.763430623 +0200
+++ openexr-2.2.1/IlmImf/ImfHeader.cpp 2020-04-20 14:35:32.472988601 +0200
@@ -869,6 +869,7 @@ Header::sanityCheck (bool isTiled, bool
}
const std::string & part_type=hasType() ? type() : "";
+
if(part_type!="" && !isSupportedType(part_type))
{
@@ -878,6 +879,7 @@ Header::sanityCheck (bool isTiled, bool
return;
}
+ bool isDeep = isDeepData(part_type);
//
// If the file is tiled, verify that the tile description has reasonable
@@ -898,7 +900,7 @@ Header::sanityCheck (bool isTiled, bool
const TileDescription &tileDesc = tileDescription();
- if (tileDesc.xSize <= 0 || tileDesc.ySize <= 0)
+ if (tileDesc.xSize <= 0 || tileDesc.ySize <= 0 || tileDesc.xSize > INT_MAX || tileDesc.ySize > INT_MAX )
throw IEX_NAMESPACE::ArgExc ("Invalid tile size in image header.");
if (maxTileWidth > 0 &&
@@ -945,7 +947,8 @@ Header::sanityCheck (bool isTiled, bool
if (!isValidCompression (this->compression()))
throw IEX_NAMESPACE::ArgExc ("Unknown compression type in image header.");
- if(isDeepData(part_type))
+
+ if( isDeep )
{
if (!isValidDeepCompression (this->compression()))
throw IEX_NAMESPACE::ArgExc ("Compression type in header not valid for deep data");
@@ -957,6 +960,8 @@ Header::sanityCheck (bool isTiled, bool
// If the file is tiled then for each channel, the type must be one of the
// predefined values, and the x and y sampling must both be 1.
//
+ // x and y sampling must currently also be 1 for deep scanline images
+ //
// If the file is not tiled then for each channel, the type must be one
// of the predefined values, the x and y coordinates of the data window's
// upper left corner must be divisible by the x and y subsampling factors,
@@ -966,7 +971,7 @@ Header::sanityCheck (bool isTiled, bool
const ChannelList &channels = this->channels();
- if (isTiled)
+ if (isTiled || isDeep)
{
for (ChannelList::ConstIterator i = channels.begin();
i != channels.end();
Index: openexr-2.2.1/IlmImf/ImfHuf.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImf/ImfHuf.cpp 2017-11-18 00:00:24.000000000 +0100
+++ openexr-2.2.1/IlmImf/ImfHuf.cpp 2020-04-20 13:12:55.775430685 +0200
@@ -1052,7 +1052,10 @@ hufUncompress (const char compressed[],
unsigned short raw[],
int nRaw)
{
- if (nCompressed == 0)
+ //
+ // need at least 20 bytes for header
+ //
+ if (nCompressed < 20 )
{
if (nRaw != 0)
notEnoughData();
@@ -1070,6 +1073,12 @@ hufUncompress (const char compressed[],
const char *ptr = compressed + 20;
+ if ( ptr + (nBits+7 )/8 > compressed+nCompressed)
+ {
+ notEnoughData();
+ return;
+ }
+
//
// Fast decoder needs at least 2x64-bits of compressed data, and
// needs to be run-able on this platform. Otherwise, fall back
Index: openexr-2.2.1/IlmImf/ImfInputFile.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImf/ImfInputFile.cpp 2017-11-18 00:00:24.000000000 +0100
+++ openexr-2.2.1/IlmImf/ImfInputFile.cpp 2020-04-20 13:12:55.775430685 +0200
@@ -474,7 +474,15 @@ InputFile::InputFile (InputPartData* par
_data (new Data (part->numThreads))
{
_data->_deleteStream=false;
- multiPartInitialize (part);
+ try
+ {
+ multiPartInitialize (part);
+ }
+ catch(...)
+ {
+ delete _data;
+ throw;
+ }
}
Index: openexr-2.2.1/IlmImf/ImfMisc.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImf/ImfMisc.cpp 2017-11-18 00:00:24.000000000 +0100
+++ openexr-2.2.1/IlmImf/ImfMisc.cpp 2020-04-20 13:12:55.775430685 +0200
@@ -114,9 +114,9 @@ bytesPerLineTable (const Header &header,
c != channels.end();
++c)
{
- int nBytes = pixelTypeSize (c.channel().type) *
- (dataWindow.max.x - dataWindow.min.x + 1) /
- c.channel().xSampling;
+ size_t nBytes = size_t(pixelTypeSize (c.channel().type)) *
+ size_t(dataWindow.max.x - dataWindow.min.x + 1) /
+ size_t(c.channel().xSampling);
for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i)
if (modp (y, c.channel().ySampling) == 0)
@@ -262,6 +262,7 @@ defaultFormat (Compressor * compressor)
}
+//obsolete
int
numLinesInBuffer (Compressor * compressor)
{
@@ -1819,6 +1820,39 @@ usesLongNames (const Header &header)
return false;
}
+namespace
+{
+// for a given compression type, return the number of scanlines
+// compressed into a single chunk
+// TODO add to API and move to ImfCompressor.cpp
+int
+numLinesInBuffer(Compression comp)
+{
+ switch(comp)
+ {
+ case NO_COMPRESSION :
+ case RLE_COMPRESSION:
+ case ZIPS_COMPRESSION:
+ return 1;
+ case ZIP_COMPRESSION:
+ return 16;
+ case PIZ_COMPRESSION:
+ return 32;
+ case PXR24_COMPRESSION:
+ return 16;
+ case B44_COMPRESSION:
+ case B44A_COMPRESSION:
+ case DWAA_COMPRESSION:
+ return 32;
+ case DWAB_COMPRESSION:
+ return 256;
+
+ default:
+ throw IEX_NAMESPACE::ArgExc ("Unknown compression type");
+ }
+}
+}
+
int
getScanlineChunkOffsetTableSize(const Header& header)
{
@@ -1828,17 +1862,11 @@ getScanlineChunkOffsetTableSize(const He
size_t maxBytesPerLine = bytesPerLineTable (header,
bytesPerLine);
- Compressor* compressor = newCompressor(header.compression(),
- maxBytesPerLine,
- header);
-
- int linesInBuffer = numLinesInBuffer (compressor);
+ int linesInBuffer = numLinesInBuffer ( header.compression() );
int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y +
linesInBuffer) / linesInBuffer;
- delete compressor;
-
return lineOffsetSize;
}
Index: openexr-2.2.1/IlmImf/ImfPizCompressor.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImf/ImfPizCompressor.cpp 2017-11-18 00:00:24.000000000 +0100
+++ openexr-2.2.1/IlmImf/ImfPizCompressor.cpp 2020-04-20 14:35:32.476988621 +0200
@@ -491,7 +491,9 @@ PizCompressor::uncompress (const char *i
// This is the cunompress function which is used by both the tiled and
// scanline decompression routines.
//
-
+
+ const char* inputEnd=inPtr+inSize;
+
//
// Special case - empty input buffer
//
@@ -502,6 +504,7 @@ PizCompressor::uncompress (const char *i
return 0;
}
+
//
// Determine the layout of the compressed pixel data
//
@@ -548,6 +551,12 @@ PizCompressor::uncompress (const char *i
AutoArray <unsigned char, BITMAP_SIZE> bitmap;
memset (bitmap, 0, sizeof (unsigned char) * BITMAP_SIZE);
+
+ if(inPtr + sizeof(unsigned short)*2 > inputEnd)
+ {
+ throw InputExc ("PIZ compressed data too short");
+ }
+
Xdr::read <CharPtrIO> (inPtr, minNonZero);
Xdr::read <CharPtrIO> (inPtr, maxNonZero);
@@ -559,8 +568,14 @@ PizCompressor::uncompress (const char *i
if (minNonZero <= maxNonZero)
{
- Xdr::read <CharPtrIO> (inPtr, (char *) &bitmap[0] + minNonZero,
- maxNonZero - minNonZero + 1);
+ size_t bytesToRead = maxNonZero - minNonZero + 1;
+ if(inPtr + bytesToRead > inputEnd)
+ {
+ throw InputExc ("PIZ compressed data too short");
+ }
+
+Xdr::read <CharPtrIO> (inPtr, (char *) &bitmap[0] + minNonZero,
+ bytesToRead);
}
AutoArray <unsigned short, USHORT_RANGE> lut;
@@ -569,6 +584,11 @@ PizCompressor::uncompress (const char *i
//
// Huffman decoding
//
+ if(inPtr + sizeof(int)> inputEnd)
+ {
+ throw InputExc ("PIZ compressed data too short");
+ }
+
int length;
Xdr::read <CharPtrIO> (inPtr, length);
Index: openexr-2.2.1/IlmImf/ImfRle.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImf/ImfRle.cpp 2017-11-18 00:00:24.000000000 +0100
+++ openexr-2.2.1/IlmImf/ImfRle.cpp 2020-04-20 13:12:55.775430685 +0200
@@ -129,6 +129,11 @@ rleUncompress (int inLength, int maxLeng
if (0 > (maxLength -= count))
return 0;
+ // check the input buffer is big enough to contain
+ // 'count' bytes of remaining data
+ if (inLength < 0)
+ return 0;
+
memcpy(out, in, count);
out += count;
in += count;
Index: openexr-2.2.1/IlmImf/ImfScanLineInputFile.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImf/ImfScanLineInputFile.cpp 2017-11-18 00:00:24.000000000 +0100
+++ openexr-2.2.1/IlmImf/ImfScanLineInputFile.cpp 2020-04-20 14:35:32.476988621 +0200
@@ -1096,8 +1096,6 @@ newLineBufferTask (TaskGroup *group,
void ScanLineInputFile::initialize(const Header& header)
{
- try
- {
_data->header = header;
_data->lineOrder = _data->header.lineOrder();
@@ -1112,6 +1110,12 @@ void ScanLineInputFile::initialize(const
size_t maxBytesPerLine = bytesPerLineTable (_data->header,
_data->bytesPerLine);
+ if(maxBytesPerLine > INT_MAX)
+ {
+ throw IEX_NAMESPACE::InputExc("maximum bytes per scanline exceeds maximum permissible size");
+ }
+
+
for (size_t i = 0; i < _data->lineBuffers.size(); i++)
{
_data->lineBuffers[i] = new LineBuffer (newCompressor
@@ -1142,13 +1146,6 @@ void ScanLineInputFile::initialize(const
_data->linesInBuffer) / _data->linesInBuffer;
_data->lineOffsets.resize (lineOffsetSize);
- }
- catch (...)
- {
- delete _data;
- _data=NULL;
- throw;
- }
}
@@ -1163,8 +1160,27 @@ ScanLineInputFile::ScanLineInputFile(Inp
_data->version = part->version;
- initialize(part->header);
+ try
+ {
+ initialize(part->header);
+ }
+ catch(...)
+ {
+ if (!_data->memoryMapped)
+ {
+ for (size_t i = 0; i < _data->lineBuffers.size(); i++)
+ {
+ if( _data->lineBuffers[i] )
+ {
+ EXRFreeAligned(_data->lineBuffers[i]->buffer);
+ _data->lineBuffers[i]->buffer=nullptr;
+ }
+ }
+ }
+ delete _data;
+ throw;
+ }
_data->lineOffsets = part->chunkOffsets;
_data->partNumber = part->partNumber;
@@ -1187,19 +1203,43 @@ ScanLineInputFile::ScanLineInputFile
_streamData->is = is;
_data->memoryMapped = is->isMemoryMapped();
- initialize(header);
-
- //
- // (TODO) this is nasty - we need a better way of working out what type of file has been used.
- // in any case I believe this constructor only gets used with single part files
- // and 'version' currently only tracks multipart state, so setting to 0 (not multipart) works for us
- //
-
- _data->version=0;
- readLineOffsets (*_streamData->is,
- _data->lineOrder,
- _data->lineOffsets,
- _data->fileIsComplete);
+ try
+ {
+
+ initialize(header);
+
+ //
+ // (TODO) this is nasty - we need a better way of working out what type of file has been used.
+ // in any case I believe this constructor only gets used with single part files
+ // and 'version' currently only tracks multipart state, so setting to 0 (not multipart) works for us
+ //
+
+ _data->version=0;
+ readLineOffsets (*_streamData->is,
+ _data->lineOrder,
+ _data->lineOffsets,
+ _data->fileIsComplete);
+ }
+ catch(...)
+ {
+ if(_data)
+ {
+ if (!_data->memoryMapped)
+ {
+ for (size_t i = 0; i < _data->lineBuffers.size(); i++)
+ {
+ if( _data->lineBuffers[i] )
+ {
+ EXRFreeAligned(_data->lineBuffers[i]->buffer);
+ _data->lineBuffers[i]->buffer=nullptr;
+ }
+ }
+ }
+ }
+ delete _streamData;
+ delete _data;
+ throw;
+ }
}
@@ -1417,6 +1457,14 @@ ScanLineInputFile::setFrameBuffer (const
offset+=2;
break;
}
+
+ //
+ // optimization mode cannot currently skip subsampled channels
+ //
+ if (i.channel().xSampling!=1 || i.channel().ySampling!=1)
+ {
+ optimizationPossible = false;
+ }
++i;
}
Index: openexr-2.2.1/IlmImf/ImfTiledInputFile.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImf/ImfTiledInputFile.cpp 2017-11-18 00:00:24.000000000 +0100
+++ openexr-2.2.1/IlmImf/ImfTiledInputFile.cpp 2020-04-20 14:35:32.476988621 +0200
@@ -703,61 +703,56 @@ TiledInputFile::TiledInputFile (const ch
IStream* is = 0;
try
{
- is = new StdIFStream (fileName);
- readMagicNumberAndVersionField(*is, _data->version);
-
- //
- // Backward compatibility to read multpart file.
- //
- if (isMultiPart(_data->version))
- {
- compatibilityInitialize(*is);
- return;
- }
-
- _data->_streamData = new InputStreamMutex();
- _data->_streamData->is = is;
- _data->header.readFrom (*_data->_streamData->is, _data->version);
- initialize();
- //read tile offsets - we are not multipart or deep
- _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,false);
- _data->_streamData->currentPosition = _data->_streamData->is->tellg();
- }
- catch (IEX_NAMESPACE::BaseExc &e)
- {
- if (_data->_streamData != 0)
+ try
{
- if (_data->_streamData->is != 0)
+ is = new StdIFStream (fileName);
+ readMagicNumberAndVersionField(*is, _data->version);
+
+ //
+ // Backward compatibility to read multpart file.
+ //
+ if (isMultiPart(_data->version))
{
- delete _data->_streamData->is;
- _data->_streamData->is = is = 0;
+ compatibilityInitialize(*is);
+ return;
}
- delete _data->_streamData;
+ _data->_streamData = new InputStreamMutex();
+ _data->_streamData->is = is;
+ _data->header.readFrom (*_data->_streamData->is, _data->version);
+ initialize();
+ //read tile offsets - we are not multipart or deep
+ _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,false);
+ _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+ }
+ catch (IEX_NAMESPACE::BaseExc &e)
+ {
+ REPLACE_EXC (e, "Cannot open image file "
+ "\"" << fileName << "\". " << e.what());
+ throw;
}
-
- if (is != 0)
- delete is;
-
- REPLACE_EXC (e, "Cannot open image file "
- "\"" << fileName << "\". " << e);
- throw;
}
catch (...)
{
- if ( _data->_streamData != 0)
+ if (!_data->memoryMapped)
{
- if ( _data->_streamData->is != 0)
+ for (size_t i = 0; i < _data->tileBuffers.size(); i++)
{
- delete _data->_streamData->is;
- _data->_streamData->is = is = 0;
+ if(_data->tileBuffers[i])
+ {
+ delete [] _data->tileBuffers[i]->buffer;
+ }
}
-
+ }
+ if ( _data->_streamData != 0)
+ {
+ delete _data->_streamData->is;
+ _data->_streamData->is = is = 0;
delete _data->_streamData;
}
- if (is != 0)
- delete is;
+ delete is;
+ delete _data;
throw;
}
}
@@ -776,38 +771,45 @@ TiledInputFile::TiledInputFile (OPENEXR_
try
{
- readMagicNumberAndVersionField(is, _data->version);
+ try
+ {
+ readMagicNumberAndVersionField(is, _data->version);
- //
- // Backward compatibility to read multpart file.
- //
- if (isMultiPart(_data->version))
- {
- compatibilityInitialize(is);
- return;
- }
-
- streamDataCreated = true;
- _data->_streamData = new InputStreamMutex();
- _data->_streamData->is = &is;
- _data->header.readFrom (*_data->_streamData->is, _data->version);
- initialize();
- // file is guaranteed to be single part, regular image
- _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,false);
- _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
- _data->_streamData->currentPosition = _data->_streamData->is->tellg();
- }
- catch (IEX_NAMESPACE::BaseExc &e)
- {
- if (streamDataCreated) delete _data->_streamData;
- delete _data;
+ //
+ // Backward compatibility to read multpart file.
+ //
+ if (isMultiPart(_data->version))
+ {
+ compatibilityInitialize(is);
+ return;
+ }
- REPLACE_EXC (e, "Cannot open image file "
- "\"" << is.fileName() << "\". " << e);
- throw;
+ streamDataCreated = true;
+ _data->_streamData = new InputStreamMutex();
+ _data->_streamData->is = &is;
+ _data->header.readFrom (*_data->_streamData->is, _data->version);
+ initialize();
+ // file is guaranteed to be single part, regular image
+ _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,false);
+ _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
+ _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+ }
+ catch (IEX_NAMESPACE::BaseExc &e)
+ {
+ REPLACE_EXC (e, "Cannot open image file "
+ "\"" << is.fileName() << "\". " << e.what());
+ throw;
+ }
}
catch (...)
{
+ if (!_data->memoryMapped)
+ {
+ for (size_t i = 0; i < _data->tileBuffers.size(); i++)
+ {
+ delete [] _data->tileBuffers[i]->buffer;
+ }
+ }
if (streamDataCreated) delete _data->_streamData;
delete _data;
throw;
@@ -831,13 +833,29 @@ TiledInputFile::TiledInputFile (const He
// we have somehow got the header.
//
- _data->_streamData->is = is;
- _data->header = header;
- _data->version = version;
- initialize();
- _data->tileOffsets.readFrom (*(_data->_streamData->is),_data->fileIsComplete,false,false);
- _data->memoryMapped = is->isMemoryMapped();
- _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+ try
+ {
+ _data->_streamData->is = is;
+ _data->header = header;
+ _data->version = version;
+ initialize();
+ _data->tileOffsets.readFrom (*(_data->_streamData->is),_data->fileIsComplete,false,false);
+ _data->memoryMapped = is->isMemoryMapped();
+ _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+ }
+ catch(...)
+ {
+ if (!_data->memoryMapped)
+ {
+ for (size_t i = 0; i < _data->tileBuffers.size(); i++)
+ {
+ delete [] _data->tileBuffers[i]->buffer;
+ }
+ }
+ delete _data->_streamData;
+ delete _data;
+ throw;
+ }
}
@@ -845,7 +863,15 @@ TiledInputFile::TiledInputFile (InputPar
{
_data = new Data (part->numThreads);
_data->_deleteStream=false;
- multiPartInitialize(part);
+ try
+ {
+ multiPartInitialize(part);
+ }
+ catch(...)
+ {
+ if (_data) delete _data;
+ throw;
+ }
}
Index: openexr-2.2.1/IlmImf/ImfTiledMisc.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImf/ImfTiledMisc.cpp 2020-04-20 13:12:55.775430685 +0200
+++ openexr-2.2.1/IlmImf/ImfTiledMisc.cpp 2020-04-20 13:50:49.167172124 +0200
@@ -363,26 +363,50 @@ getTiledChunkOffsetTableSize(const Heade
//
int lineOffsetSize = 0;
const TileDescription &desc = header.tileDescription();
- switch (desc.mode)
+ try
{
- case ONE_LEVEL:
- case MIPMAP_LEVELS:
- for (int i = 0; i < numXLevels; i++)
- lineOffsetSize += numXTiles[i] * numYTiles[i];
+ switch (desc.mode)
+ {
+ case ONE_LEVEL:
+ case MIPMAP_LEVELS:
+ for (int i = 0; i < numXLevels; i++)
+ {
+ lineOffsetSize += static_cast<Int64>(numXTiles[i]) * static_cast<Int64>(numYTiles[i]);
+ if ( lineOffsetSize > static_cast<Int64>(std::numeric_limits<int>::max()) )
+ {
+ throw IEX_NAMESPACE::LogicExc("Maximum number of tiles exceeded");
+ }
+ }
break;
- case RIPMAP_LEVELS:
- for (int i = 0; i < numXLevels; i++)
- for (int j = 0; j < numYLevels; j++)
- lineOffsetSize += numXTiles[i] * numYTiles[j];
+ case RIPMAP_LEVELS:
+ for (int i = 0; i < numXLevels; i++)
+ {
+ for (int j = 0; j < numYLevels; j++)
+ {
+ lineOffsetSize += static_cast<Int64>(numXTiles[i]) * static_cast<Int64>(numYTiles[j]);
+ if ( lineOffsetSize > static_cast<Int64>(std::numeric_limits<int>::max()) )
+ {
+ throw IEX_NAMESPACE::LogicExc("Maximum number of tiles exceeded");
+ }
+ }
+ }
break;
- case NUM_LEVELMODES :
- throw IEX_NAMESPACE::LogicExc("Bad level mode getting chunk offset table size");
- }
+ case NUM_LEVELMODES :
+ throw IEX_NAMESPACE::LogicExc("Bad level mode getting chunk offset table size");
+ }
+ delete[] numXTiles;
+ delete[] numYTiles;
- delete[] numXTiles;
- delete[] numYTiles;
+ return static_cast<int>(lineOffsetSize);
- return lineOffsetSize;
+ }
+ catch(...)
+ {
+ delete[] numXTiles;
+ delete[] numYTiles;
+
+ throw;
+ }
}
Index: openexr-2.2.1/IlmImfTest/testMultiPartApi.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImfTest/testMultiPartApi.cpp 2017-11-18 00:00:25.000000000 +0100
+++ openexr-2.2.1/IlmImfTest/testMultiPartApi.cpp 2020-04-20 13:12:55.775430685 +0200
@@ -459,6 +459,21 @@ generateRandomFile (int partCount, const
}
}
+ for (size_t i = 0 ; i < parts.size() ; ++i )
+ {
+ int partType = partTypes[i];
+
+ if (partType == 0)
+ {
+ delete (OutputPart*) parts[i];
+ }
+ else
+ {
+ delete (TiledOutputPart*) parts[i];
+ }
+
+ }
+
delete[] tiledHalfData;
delete[] tiledUintData;
delete[] tiledFloatData;
Index: openexr-2.2.1/IlmImfTest/testMultiPartThreading.cpp
===================================================================
--- openexr-2.2.1.orig/IlmImfTest/testMultiPartThreading.cpp 2017-11-18 00:00:25.000000000 +0100
+++ openexr-2.2.1/IlmImfTest/testMultiPartThreading.cpp 2020-04-20 14:35:32.476988621 +0200
@@ -622,6 +622,18 @@ generateRandomFile (int partCount, const
}
}
+ for (int i = 0; i < partCount; i++)
+ {
+ if (partTypes[i] == 0)
+ {
+ delete (OutputPart*) parts[i];
+ }
+ else
+ {
+ delete (TiledOutputPart*) parts[i];
+ }
+ }
+
delete threadPool;
delete[] tiledHalfData;
Index: openexr-2.2.1/exrmakepreview/makePreview.cpp
===================================================================
--- openexr-2.2.1.orig/exrmakepreview/makePreview.cpp 2020-04-20 13:12:55.775430685 +0200
+++ openexr-2.2.1/exrmakepreview/makePreview.cpp 2020-04-20 14:15:38.178826125 +0200
@@ -123,8 +123,8 @@ generatePreview (const char inFileName[]
previewHeight = max (int (h / (w * a) * previewWidth + .5f), 1);
previewPixels.resizeErase (previewHeight, previewWidth);
- float fx = (previewWidth > 0)? (float (w - 1) / (previewWidth - 1)): 1;
- float fy = (previewHeight > 0)? (float (h - 1) / (previewHeight - 1)): 1;
+ double fx = (previewWidth > 0)? (double (w - 1) / (previewWidth - 1)): 1;
+ double fy = (previewHeight > 0)? (double (h - 1) / (previewHeight - 1)): 1;
float m = Math<float>::pow (2.f, clamp (exposure + 2.47393f, -20.f, 20.f));
for (int y = 0; y < previewHeight; ++y)