diff --git a/src/iptc.cpp b/src/iptc.cpp index a00e489e..a3bb6e1d 100644 --- a/src/iptc.cpp +++ b/src/iptc.cpp @@ -439,6 +439,7 @@ namespace Exiv2 { std::cerr << "IptcParser::decode, size = " << size << "\n"; #endif const byte* pRead = pData; + const byte* const pEnd = pData + size; iptcData.clear(); uint16_t record = 0; @@ -446,7 +447,7 @@ namespace Exiv2 { uint32_t sizeData = 0; byte extTest = 0; - while (pRead + 3 < pData + size) { + while (6 <= static_cast(pEnd - pRead)) { // First byte should be a marker. If it isn't, scan forward and skip // the chunk bytes present in some images. This deviates from the // standard, which advises to treat such cases as errors. @@ -460,6 +461,7 @@ namespace Exiv2 { uint16_t sizeOfSize = (getUShort(pRead, bigEndian) & 0x7FFF); if (sizeOfSize > 4) return 5; pRead += 2; + if (sizeOfSize > static_cast(pEnd - pRead)) return 6; sizeData = 0; for (; sizeOfSize > 0; --sizeOfSize) { sizeData |= *pRead++ << (8 *(sizeOfSize-1)); @@ -470,7 +472,7 @@ namespace Exiv2 { sizeData = getUShort(pRead, bigEndian); pRead += 2; } - if (pRead + sizeData <= pData + size) { + if (sizeData <= static_cast(pEnd - pRead)) { int rc = 0; if ((rc = readData(iptcData, dataSet, record, pRead, sizeData)) != 0) { #ifndef SUPPRESS_WARNINGS @@ -484,6 +486,7 @@ namespace Exiv2 { else { EXV_WARNING << "IPTC dataset " << IptcKey(dataSet, record) << " has invalid size " << sizeData << "; skipped.\n"; + return 7; } #endif pRead += sizeData; diff --git a/test/data/issue_867_poc.psd b/test/data/issue_867_poc.psd new file mode 100644 index 00000000..635fd82f Binary files /dev/null and b/test/data/issue_867_poc.psd differ diff --git a/tests/bugfixes/github/test_issue_867.py b/tests/bugfixes/github/test_issue_867.py new file mode 100644 index 00000000..2b8248df --- /dev/null +++ b/tests/bugfixes/github/test_issue_867.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +from system_tests import CaseMeta, path + + +class OutOfBoundsReadInIptcParserDecode(metaclass=CaseMeta): + """ + Regression test for the bug described in: + https://github.com/Exiv2/exiv2/issues/867 + """ + url = "https://github.com/Exiv2/exiv2/issues/867" + + filename = path("$data_path/issue_867_poc.psd") + commands = ["$exiv2 $filename"] + stdout = ["""File name : $filename +File size : 9830 Bytes +MIME type : image/x-photoshop +Image size : 150 x 91 +""" +] + stderr = [ + """Warning: Failed to decode IPTC metadata. +$filename: No Exif data found in the file +""" +] + retval = [253]