diff options
author | Caolán McNamara <caolanm@redhat.com> | 2020-12-23 19:20:16 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2020-12-24 12:53:09 +0100 |
commit | 95407c39168d186ee44e67b1a6a4bcf592c58b84 (patch) | |
tree | 24fc693eb9d93b2e7fed0c68b35e6cf03cb4bd58 | |
parent | 7efbe1a977247d91896acb389c2bbd563caf6fa3 (diff) |
ofz#28902 uncaught exception
Change-Id: I94dc0e2c8466546772ae7fdd1a0f3501a8f9bfaa
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108245
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | vcl/source/filter/png/pngread.cxx | 117 |
1 files changed, 63 insertions, 54 deletions
diff --git a/vcl/source/filter/png/pngread.cxx b/vcl/source/filter/png/pngread.cxx index cda1c3e9e4b5..2155648d1273 100644 --- a/vcl/source/filter/png/pngread.cxx +++ b/vcl/source/filter/png/pngread.cxx @@ -256,68 +256,77 @@ PNGReaderImpl::~PNGReaderImpl() bool PNGReaderImpl::ReadNextChunk() { - if( maChunkIter == maChunkSeq.end() ) + try { - // get the next chunk from the stream - - // unless we are at the end of the PNG stream - if (!mrPNGStream.good() || mrPNGStream.remainingSize() < 8) - return false; - if( !maChunkSeq.empty() && (maChunkSeq.back().nType == PNGCHUNK_IEND) ) - return false; - - PNGReader::ChunkData aDummyChunk; - maChunkIter = maChunkSeq.insert( maChunkSeq.end(), aDummyChunk ); - PNGReader::ChunkData& rChunkData = *maChunkIter; - - // read the chunk header - mnChunkLen = 0; - mnChunkType = 0; - mrPNGStream.ReadInt32( mnChunkLen ).ReadUInt32( mnChunkType ); - rChunkData.nType = mnChunkType; - - // fdo#61847 truncate over-long, trailing chunks - const std::size_t nStreamPos = mrPNGStream.Tell(); - if( mnChunkLen < 0 || nStreamPos + mnChunkLen >= mnStreamSize ) - mnChunkLen = mnStreamSize - nStreamPos; - - // calculate chunktype CRC (swap it back to original byte order) - sal_uInt32 nChunkType = mnChunkType; - #if defined(__LITTLEENDIAN) || defined(OSL_LITENDIAN) - nChunkType = OSL_SWAPDWORD( nChunkType ); - #endif - sal_uInt32 nCRC32 = rtl_crc32( 0, &nChunkType, 4 ); - - // read the chunk data and check the CRC - if( mnChunkLen && !mrPNGStream.eof() ) + if( maChunkIter == maChunkSeq.end() ) { - rChunkData.aData.resize( mnChunkLen ); - - sal_Int32 nBytesRead = 0; - do + // get the next chunk from the stream + + // unless we are at the end of the PNG stream + if (!mrPNGStream.good() || mrPNGStream.remainingSize() < 8) + return false; + if( !maChunkSeq.empty() && (maChunkSeq.back().nType == PNGCHUNK_IEND) ) + return false; + + PNGReader::ChunkData aDummyChunk; + maChunkIter = maChunkSeq.insert( maChunkSeq.end(), aDummyChunk ); + PNGReader::ChunkData& rChunkData = *maChunkIter; + + // read the chunk header + mnChunkLen = 0; + mnChunkType = 0; + mrPNGStream.ReadInt32( mnChunkLen ).ReadUInt32( mnChunkType ); + rChunkData.nType = mnChunkType; + + // fdo#61847 truncate over-long, trailing chunks + const std::size_t nStreamPos = mrPNGStream.Tell(); + if( mnChunkLen < 0 || nStreamPos + mnChunkLen >= mnStreamSize ) + mnChunkLen = mnStreamSize - nStreamPos; + + // calculate chunktype CRC (swap it back to original byte order) + sal_uInt32 nChunkType = mnChunkType; + #if defined(__LITTLEENDIAN) || defined(OSL_LITENDIAN) + nChunkType = OSL_SWAPDWORD( nChunkType ); + #endif + sal_uInt32 nCRC32 = rtl_crc32( 0, &nChunkType, 4 ); + + // read the chunk data and check the CRC + if( mnChunkLen && !mrPNGStream.eof() ) { - sal_uInt8& rPtr = rChunkData.aData[nBytesRead]; - nBytesRead += mrPNGStream.ReadBytes(&rPtr, mnChunkLen - nBytesRead); - } while (nBytesRead < mnChunkLen && mrPNGStream.good()); + rChunkData.aData.resize( mnChunkLen ); + + sal_Int32 nBytesRead = 0; + do + { + sal_uInt8& rPtr = rChunkData.aData[nBytesRead]; + nBytesRead += mrPNGStream.ReadBytes(&rPtr, mnChunkLen - nBytesRead); + } while (nBytesRead < mnChunkLen && mrPNGStream.good()); - nCRC32 = rtl_crc32( nCRC32, rChunkData.aData.data(), mnChunkLen ); - maDataIter = rChunkData.aData.begin(); + nCRC32 = rtl_crc32( nCRC32, rChunkData.aData.data(), mnChunkLen ); + maDataIter = rChunkData.aData.begin(); + } + sal_uInt32 nCheck(0); + mrPNGStream.ReadUInt32( nCheck ); + if (!mbIgnoreCRC && nCRC32 != nCheck) + return false; } - sal_uInt32 nCheck(0); - mrPNGStream.ReadUInt32( nCheck ); - if (!mbIgnoreCRC && nCRC32 != nCheck) - return false; + else + { + // the next chunk was already read + mnChunkType = (*maChunkIter).nType; + mnChunkLen = (*maChunkIter).aData.size(); + maDataIter = (*maChunkIter).aData.begin(); + } + + ++maChunkIter; + return mnChunkType != PNGCHUNK_IEND; } - else + catch (const SvStreamEOFException&) { - // the next chunk was already read - mnChunkType = (*maChunkIter).nType; - mnChunkLen = (*maChunkIter).aData.size(); - maDataIter = (*maChunkIter).aData.begin(); + mbStatus = false; + SAL_WARN("vcl", "EOF"); } - - ++maChunkIter; - return mnChunkType != PNGCHUNK_IEND; + return false; } const std::vector< vcl::PNGReader::ChunkData >& PNGReaderImpl::GetAllChunks() |