diff --git a/src/image.cpp b/src/image.cpp index 1428e6b0..cde7d4a0 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -467,20 +467,20 @@ namespace Exiv2 { seekOrThrow(io, restore, BasicIo::beg, kerCorruptedMetadata); } } else if ( option == kpsRecursive && tag == 0x83bb /* IPTCNAA */ ) { + if (count > 0) { + if (static_cast(Safe::add(count, offset)) > io.size()) { + throw Error(kerCorruptedMetadata); + } - if (static_cast(Safe::add(count, offset)) > io.size()) { - throw Error(kerCorruptedMetadata); + const long restore = io.tell(); + seekOrThrow(io, offset, BasicIo::beg, kerCorruptedMetadata); // position + std::vector bytes(count) ; // allocate memory + // TODO: once we have C++11 use bytes.data() + readOrThrow(io, &bytes[0], count, kerCorruptedMetadata); + seekOrThrow(io, restore, BasicIo::beg, kerCorruptedMetadata); + // TODO: once we have C++11 use bytes.data() + IptcData::printStructure(out, makeSliceUntil(&bytes[0], count), depth); } - - const long restore = io.tell(); - seekOrThrow(io, offset, BasicIo::beg, kerCorruptedMetadata); // position - std::vector bytes(count) ; // allocate memory - // TODO: once we have C++11 use bytes.data() - readOrThrow(io, &bytes[0], count, kerCorruptedMetadata); - seekOrThrow(io, restore, BasicIo::beg, kerCorruptedMetadata); - // TODO: once we have C++11 use bytes.data() - IptcData::printStructure(out, makeSliceUntil(&bytes[0], count), depth); - } else if ( option == kpsRecursive && tag == 0x927c /* MakerNote */ && count > 10) { const long restore = io.tell(); // save diff --git a/test/data/issue_ghsa_g44w_q3vm_gwjq_poc.jpg b/test/data/issue_ghsa_g44w_q3vm_gwjq_poc.jpg new file mode 100644 index 00000000..039b43d6 Binary files /dev/null and b/test/data/issue_ghsa_g44w_q3vm_gwjq_poc.jpg differ diff --git a/tests/bugfixes/github/test_issue_g44w_q3vm_gwjq.py b/tests/bugfixes/github/test_issue_g44w_q3vm_gwjq.py new file mode 100644 index 00000000..cf17b65d --- /dev/null +++ b/tests/bugfixes/github/test_issue_g44w_q3vm_gwjq.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +from system_tests import CaseMeta, CopyTmpFiles, path, check_no_ASAN_UBSAN_errors +import unittest + +@unittest.skip("Skipping test using option -pR (only for Debug mode)") +class ImagePrintIFDStructureZeroCountAssert(metaclass=CaseMeta): + """ + Regression test for the bug described in: + https://github.com/Exiv2/exiv2/security/advisories/GHSA-g44w-q3vm-gwjq + """ + url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-g44w-q3vm-gwjq" + + filename = path("$data_path/issue_ghsa_g44w_q3vm_gwjq_poc.jpg") + commands = ["$exiv2 -pR $filename"] + stderr = ["""invalid type in tiff structure0 +Exiv2 exception in print action for file $filename: +$kerInvalidTypeValue +"""] + retval = [1] + + compare_stdout = check_no_ASAN_UBSAN_errors