diff --git a/src/pgfimage.cpp b/src/pgfimage.cpp index d7bbea3f..c78efdd5 100644 --- a/src/pgfimage.cpp +++ b/src/pgfimage.cpp @@ -31,6 +31,7 @@ #include "image.hpp" #include "pngimage.hpp" #include "basicio.hpp" +#include "enforce.hpp" #include "error.hpp" #include "futils.hpp" @@ -128,13 +129,18 @@ namespace Exiv2 { // And now, the most interresting, the user data byte array where metadata are stored as small image. - long size = 8 + headerSize - io_->tell(); + enforce(headerSize <= std::numeric_limits::max() - 8, kerCorruptedMetadata); +#if LONG_MAX < UINT_MAX + enforce(headerSize + 8 <= static_cast(std::numeric_limits::max()), + kerCorruptedMetadata); +#endif + long size = static_cast(headerSize) + 8 - io_->tell(); #ifdef DEBUG std::cout << "Exiv2::PgfImage::readMetadata: Found Image data (" << size << " bytes)\n"; #endif - if (size < 0) throw Error(kerInputDataReadFailed); + if (size < 0 || static_cast(size) > io_->size()) throw Error(kerInputDataReadFailed); if (size == 0) return; DataBuf imgData(size); diff --git a/test/data/issue_847_poc.pgf b/test/data/issue_847_poc.pgf new file mode 100644 index 00000000..271cc239 Binary files /dev/null and b/test/data/issue_847_poc.pgf differ diff --git a/tests/bugfixes/github/test_issue_847.py b/tests/bugfixes/github/test_issue_847.py new file mode 100644 index 00000000..9fd55539 --- /dev/null +++ b/tests/bugfixes/github/test_issue_847.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +from system_tests import CaseMeta, path + + +class LargeAllocationInPgfReadMetadata(metaclass=CaseMeta): + """ + Regression test for the bug described in: + https://github.com/Exiv2/exiv2/issues/847 + + An unchecked allocation size causes a std::bad_alloc to + be thrown. + """ + url = "https://github.com/Exiv2/exiv2/issues/847" + + filename = path("$data_path/issue_847_poc.pgf") + commands = ["$exiv2 $filename"] + stdout = [""] + stderr = [ + """$exiv2_exception_message $filename: +Failed to read input data +"""] + retval = [1]