diff --git a/src/pngimage.cpp b/src/pngimage.cpp index 87cf980c..ea3606a4 100644 --- a/src/pngimage.cpp +++ b/src/pngimage.cpp @@ -253,7 +253,7 @@ namespace Exiv2 { if (bufRead != cheaderBuf.size_) throw Error(kerInputDataReadFailed); // Decode chunk data length. - uint32_t dataOffset = Exiv2::getULong(cheaderBuf.pData_, Exiv2::bigEndian); + const uint32_t dataOffset = Exiv2::getULong(cheaderBuf.pData_, Exiv2::bigEndian); for (int i = 4; i < 8; i++) { chType[i-4]=cheaderBuf.pData_[i]; } @@ -268,7 +268,8 @@ namespace Exiv2 { } DataBuf buff(dataOffset); - io_->read(buff.pData_,dataOffset); + bufRead = io_->read(buff.pData_,dataOffset); + enforce(bufRead == static_cast(dataOffset), kerFailedToReadImageData); io_->seek(restore, BasicIo::beg); // format output @@ -287,7 +288,8 @@ namespace Exiv2 { if ( bPrint ) { io_->seek(dataOffset, BasicIo::cur);// jump to checksum byte checksum[4]; - io_->read(checksum,4); + bufRead = io_->read(checksum,4); + enforce(bufRead == 4, kerFailedToReadImageData); io_->seek(restore, BasicIo::beg) ;// restore file pointer out << Internal::stringFormat("%8d | %-5s |%8d | " @@ -318,9 +320,12 @@ namespace Exiv2 { DataBuf dataBuf; byte* data = new byte[dataOffset+1]; data[dataOffset] = 0; - io_->read(data,dataOffset); + bufRead = io_->read(data,dataOffset); + enforce(bufRead == static_cast(dataOffset), kerFailedToReadImageData); io_->seek(restore, BasicIo::beg); uint32_t name_l = (uint32_t) std::strlen((const char*)data)+1; // leading string length + enforce(name_l <= dataOffset, kerCorruptedMetadata); + uint32_t start = name_l; bool bLF = false; diff --git a/test/data/issue_828_poc.png b/test/data/issue_828_poc.png new file mode 100644 index 00000000..40de828f Binary files /dev/null and b/test/data/issue_828_poc.png differ diff --git a/tests/bugfixes/github/test_issue_828.py b/tests/bugfixes/github/test_issue_828.py new file mode 100644 index 00000000..d17db99d --- /dev/null +++ b/tests/bugfixes/github/test_issue_828.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- + +from system_tests import CaseMeta, path +import unittest + +@unittest.skip("Skipping test using option -pR (only for Debug mode)") +class SegmentationFaultPngImage(metaclass=CaseMeta): + """ + Regression test for the bug described in: + https://github.com/Exiv2/exiv2/issues/828 + """ + url = "https://github.com/Exiv2/exiv2/issues/828" + + filename = path("$data_path/issue_828_poc.png") + commands = ["$exiv2 -pR $filename"] + stdout = ["""STRUCTURE OF PNG FILE: $filename + address | chunk | length | data | checksum + 8 | IHDR | 13 | ............. | 0x085f152d + 33 | gAMA | 4 | .... | 0x0bfc6105 + 49 | PLTE | 717 | .........].....Y..q..}..q..y.. | 0x7b35a4a5 + 778 | tRNS | 238 | -U...............}...=..e..... | 0xebd29012 + 1028 | bKGD | 1 | . | 0xcfb7d237 + 1041 | tEXt | 14 | Title.IceAlpha | 0xc562f8cb + 1067 | tEXt | 31 | Author.Pieter S. van der Meule | 0x6bfe26a8 + 1110 | tEXt | 411 | Description.The original image | 0xe12effe4 +""" +] + stderr = [ + """$exiv2_exception_message $filename: +$kerCorruptedMetadata +"""] + retval = [1]