vcl/source/filter/png/PngImageReader.cxx |   21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

New commits:
commit a5b6255ee4c4b4df8141235cd4ee392d86e7fb5c
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Mon Dec 4 13:03:10 2023 +0000
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Mon Dec 4 15:25:43 2023 +0100

    ofz#64582 Out-of-memory
    
    Change-Id: I862d558ffcf7d0347bf6b9e960b6f00c08c9e8fb
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160310
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/vcl/source/filter/png/PngImageReader.cxx 
b/vcl/source/filter/png/PngImageReader.cxx
index 860bd807a685..d29c0b90c473 100644
--- a/vcl/source/filter/png/PngImageReader.cxx
+++ b/vcl/source/filter/png/PngImageReader.cxx
@@ -209,7 +209,6 @@ void getImportantChunks(SvStream& rInStream, SvStream& 
rOutStream, sal_uInt32 nW
                         sal_uInt32 nHeight)
 {
     sal_uInt64 nPos = rInStream.Tell();
-    sal_uInt32 nChunkSize, nChunkType;
     rInStream.SetEndian(SvStreamEndian::BIG);
     rOutStream.SetEndian(SvStreamEndian::BIG);
     rOutStream.WriteUInt64(PNG_SIGNATURE);
@@ -232,6 +231,7 @@ void getImportantChunks(SvStream& rInStream, SvStream& 
rOutStream, sal_uInt32 nW
                    + PNG_CRC_SIZE);
     while (rInStream.good())
     {
+        sal_uInt32 nChunkSize(0), nChunkType(0);
         rInStream.ReadUInt32(nChunkSize);
         rInStream.ReadUInt32(nChunkType);
         bool bBreakOuter = false;
@@ -255,13 +255,20 @@ void getImportantChunks(SvStream& rInStream, SvStream& 
rOutStream, sal_uInt32 nW
             {
                 // Seek back to start of chunk
                 rInStream.SeekRel(-PNG_TYPE_SIZE - PNG_SIZE_SIZE);
+                const size_t nDataSize = PNG_SIZE_SIZE + PNG_TYPE_SIZE
+                                         + static_cast<size_t>(nChunkSize) + 
PNG_CRC_SIZE;
+                if (nDataSize > rInStream.remainingSize())
+                {
+                    SAL_WARN("vcl.filter", "png claims record of size: "
+                                               << nDataSize << ", but only "
+                                               << rInStream.remainingSize() << 
" available.");
+                    bBreakOuter = true;
+                    break;
+                }
                 // Copy chunk to rOutStream
-                std::vector<uint8_t> aData(nChunkSize + PNG_TYPE_SIZE + 
PNG_SIZE_SIZE
-                                           + PNG_CRC_SIZE);
-                rInStream.ReadBytes(aData.data(),
-                                    PNG_TYPE_SIZE + PNG_SIZE_SIZE + nChunkSize 
+ PNG_CRC_SIZE);
-                rOutStream.WriteBytes(aData.data(),
-                                      PNG_TYPE_SIZE + PNG_SIZE_SIZE + 
nChunkSize + PNG_CRC_SIZE);
+                std::vector<uint8_t> aData(nDataSize);
+                rInStream.ReadBytes(aData.data(), nDataSize);
+                rOutStream.WriteBytes(aData.data(), nDataSize);
                 break;
             }
         }

Reply via email to