From b35c43e7c2409978a0c45f35c2ec8c7f625469df Mon Sep 17 00:00:00 2001 From: Kevin Backhouse Date: Fri, 17 May 2019 11:45:42 +0100 Subject: [PATCH] Remove call to atol, which might read off the end of the buffer. (#870) --- src/pngchunk_int.cpp | 13 ++++++++++--- test/data/issue_869_poc.png | Bin 0 -> 188 bytes tests/bugfixes/github/test_issue_845.py | 2 +- tests/bugfixes/github/test_issue_869.py | 21 +++++++++++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 test/data/issue_869_poc.png create mode 100644 tests/bugfixes/github/test_issue_869.py diff --git a/src/pngchunk_int.cpp b/src/pngchunk_int.cpp index 714b95b4..adab5715 100644 --- a/src/pngchunk_int.cpp +++ b/src/pngchunk_int.cpp @@ -653,9 +653,17 @@ namespace Exiv2 { } } - const char* startOfLength = sp; + // Parse the length. + long length = 0; while ('0' <= *sp && *sp <= '9') { + // Compute the new length using unsigned long, so that we can + // check for overflow. + const unsigned long newlength = (10 * static_cast(length)) + (*sp - '0'); + if (newlength > static_cast(std::numeric_limits::max())) { + return DataBuf(); // Integer overflow. + } + length = static_cast(newlength); sp++; if (sp == eot ) { @@ -667,8 +675,7 @@ namespace Exiv2 { return DataBuf(); } - long length = (long) atol(startOfLength); - enforce(0 <= length && length <= (eot - sp)/2, Exiv2::kerCorruptedMetadata); + enforce(length <= (eot - sp)/2, Exiv2::kerCorruptedMetadata); // Allocate space if (length == 0) diff --git a/test/data/issue_869_poc.png b/test/data/issue_869_poc.png new file mode 100644 index 0000000000000000000000000000000000000000..51d770cca48627ad3c32fca89c70b4d7f42b9d20 GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^xS*uCQB@D%i|L9l(v<7y#+W9RdIV literal 0 HcmV?d00001 diff --git a/tests/bugfixes/github/test_issue_845.py b/tests/bugfixes/github/test_issue_845.py index 87814e9d..cc89bbf7 100644 --- a/tests/bugfixes/github/test_issue_845.py +++ b/tests/bugfixes/github/test_issue_845.py @@ -18,6 +18,6 @@ class LargeAllocationInPngChunk(metaclass=CaseMeta): stdout = [""] stderr = [ """$exiv2_exception_message $filename: -$kerCorruptedMetadata +Failed to read image data """] retval = [1] diff --git a/tests/bugfixes/github/test_issue_869.py b/tests/bugfixes/github/test_issue_869.py new file mode 100644 index 00000000..d094e874 --- /dev/null +++ b/tests/bugfixes/github/test_issue_869.py @@ -0,0 +1,21 @@ +# -*- 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/869 + """ + url = "https://github.com/Exiv2/exiv2/issues/869" + + filename = path("$data_path/issue_869_poc.png") + commands = ["$exiv2 $filename"] + stdout = [""] + stderr = [ + """Exiv2 exception in print action for file $filename: +Failed to read image data +""" +] + retval = [1]