vcl/source/gdi/dibtools.cxx | 63 ++++++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 16 deletions(-)
New commits: commit 326418924702ef3a991db13c8d3e0f844985dada Author: David Tardon <dtar...@redhat.com> Date: Fri Jan 22 16:30:28 2016 +0100 sanitize input to avoid large allocation Also avoid use of zero-sized array. (cherry picked from commit 2f0cf9872644cb83a3125bb582a7773d8eea2cb6) fix build (cherry picked from commit 05e078fd9578a63a302fce616227f3bd1bdbea6a) Change-Id: I843f6ffa7821b10676e590a5744b1cdc4864913b Reviewed-on: https://gerrit.libreoffice.org/21788 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> diff --git a/vcl/source/gdi/dibtools.cxx b/vcl/source/gdi/dibtools.cxx index 8cfc630..10c70e9 100644 --- a/vcl/source/gdi/dibtools.cxx +++ b/vcl/source/gdi/dibtools.cxx @@ -801,7 +801,7 @@ bool ImplReadDIBBody( SvStream& rIStm, Bitmap& rBmp, Bitmap* pBmpAlpha, sal_uLon sal_uInt16 nColors(0); SvStream* pIStm; std::unique_ptr<SvMemoryStream> pMemStm; - sal_uInt8* pData = nullptr; + std::vector<sal_uInt8> aData; if (aHeader.nBitCount <= 8) { @@ -826,22 +826,58 @@ bool ImplReadDIBBody( SvStream& rIStm, Bitmap& rBmp, Bitmap* pBmpAlpha, sal_uLon rIStm.ReadUInt32( nCodedSize ).ReadUInt32( nUncodedSize ).ReadUInt32( aHeader.nCompression ); if (nCodedSize > rIStm.remainingSize()) nCodedSize = sal_uInt32(rIStm.remainingSize()); - pData = static_cast<sal_uInt8*>(rtl_allocateMemory( nUncodedSize )); + size_t nSizeInc(4 * rIStm.remainingSize()); + if (nUncodedSize < nSizeInc) + nSizeInc = nUncodedSize; - // decode buffer - nCodedPos = rIStm.Tell(); - aCodec.BeginCompression(); - aCodec.Read( rIStm, pData, nUncodedSize ); - aCodec.EndCompression(); - - // Seek behind the encoded block. There might have been bytes left or the codec might have read more than necessary. - rIStm.Seek(nCodedSize + nCodedPos); + if (nSizeInc > 0) + { + // decode buffer + nCodedPos = rIStm.Tell(); + aCodec.BeginCompression(); + aData.resize(nSizeInc); + size_t nDataPos(0); + while (nUncodedSize > nDataPos) + { + assert(aData.size() > nDataPos); + const size_t nToRead(std::min<size_t>(nUncodedSize - nDataPos, aData.size() - nDataPos)); + assert(nToRead > 0); + assert(!aData.empty()); + const long nRead = aCodec.Read(rIStm, &aData.front() + nDataPos, sal_uInt32(nToRead)); + if (nRead > 0) + { + nDataPos += static_cast<unsigned long>(nRead); + // we haven't read everything yet: resize buffer and continue + if (nDataPos < nUncodedSize) + aData.resize(aData.size() + nSizeInc); + } + else + { + break; + } + } + // truncate the data buffer to actually read size + aData.resize(nDataPos); + // set the real uncoded size + nUncodedSize = sal_uInt32(aData.size()); + aCodec.EndCompression(); + + // Seek behind the encoded block. There might have been bytes left or the codec might have read more than necessary. + rIStm.Seek(nCodedSize + nCodedPos); + } + else + { + // add something so we can take address of the first element + aData.resize(1); + nUncodedSize = 0; + } // set decoded bytes to memory stream, // from which we will read the bitmap data pMemStm.reset( new SvMemoryStream); pIStm = pMemStm.get(); - pMemStm->SetBuffer( pData, nUncodedSize, false, nUncodedSize ); + assert(!aData.empty()); + pMemStm->SetBuffer( &aData.front(), nUncodedSize, false, nUncodedSize ); nOffset = 0; } else @@ -881,11 +917,6 @@ bool ImplReadDIBBody( SvStream& rIStm, Bitmap& rBmp, Bitmap* pBmpAlpha, sal_uLon } } - if( pData ) - { - rtl_freeMemory(pData); - } - Bitmap::ReleaseAccess(pAcc); if(bAlphaPossible) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits