diff --git a/src/psdimage.cpp b/src/psdimage.cpp index 8ed67544..0f6b2549 100644 --- a/src/psdimage.cpp +++ b/src/psdimage.cpp @@ -203,6 +203,8 @@ namespace Exiv2 { while (resourcesLength > 0) { + enforce(resourcesLength >= 8, Exiv2::kerCorruptedMetadata); + resourcesLength -= 8; if (io_->read(buf, 8) != 8) { throw Error(kerNotAnImage, "Photoshop"); @@ -216,9 +218,13 @@ namespace Exiv2 { uint32_t resourceNameLength = buf[6] & ~1; // skip the resource name, plus any padding + enforce(resourceNameLength <= resourcesLength, Exiv2::kerCorruptedMetadata); + resourcesLength -= resourceNameLength; io_->seek(resourceNameLength, BasicIo::cur); // read resource size + enforce(resourcesLength >= 4, Exiv2::kerCorruptedMetadata); + resourcesLength -= 4; if (io_->read(buf, 4) != 4) { throw Error(kerNotAnImage, "Photoshop"); @@ -230,11 +236,12 @@ namespace Exiv2 { std::cerr << std::hex << "resourceId: " << resourceId << std::dec << " length: " << resourceSize << std::hex << "\n"; #endif + enforce(resourceSize <= resourcesLength, Exiv2::kerCorruptedMetadata); readResourceBlock(resourceId, resourceSize); resourceSize = (resourceSize + 1) & ~1; // pad to even + enforce(resourceSize <= resourcesLength, Exiv2::kerCorruptedMetadata); + resourcesLength -= resourceSize; io_->seek(curOffset + resourceSize, BasicIo::beg); - resourcesLength -= Safe::add(Safe::add(static_cast(12), resourceNameLength), - resourceSize); } } // PsdImage::readMetadata diff --git a/test/data/issue_855_poc.psd b/test/data/issue_855_poc.psd new file mode 100644 index 00000000..823fccf8 Binary files /dev/null and b/test/data/issue_855_poc.psd differ diff --git a/tests/bugfixes/github/test_issue_855.py b/tests/bugfixes/github/test_issue_855.py new file mode 100644 index 00000000..c1c78bdc --- /dev/null +++ b/tests/bugfixes/github/test_issue_855.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +from system_tests import CaseMeta, path + + +class OutOfMemoryInPsdImageReadMetadata(metaclass=CaseMeta): + """ + Regression test for the bug described in: + https://github.com/Exiv2/exiv2/issues/855 + + There is no bounds check on the value of resourceSize, + leading to an out-of-memory error. + """ + url = "https://github.com/Exiv2/exiv2/issues/855" + + filename = path("$data_path/issue_855_poc.psd") + commands = ["$exiv2 $filename"] + stdout = [""] + stderr = ["""Warning: Failed to decode IPTC metadata. +Exiv2 exception in print action for file $filename: +corrupted image metadata +""" +] + retval = [1]