[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - vcl/source

David Tardon dtardon at redhat.com
Sat Jan 30 06:47:24 PST 2016


 vcl/source/gdi/dibtools.cxx |   63 ++++++++++++++++++++++++++++++++------------
 1 file changed, 47 insertions(+), 16 deletions(-)

New commits:
commit 326418924702ef3a991db13c8d3e0f844985dada
Author: David Tardon <dtardon at 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 <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at 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)


More information about the Libreoffice-commits mailing list