diff --git a/src/basicio.cpp b/src/basicio.cpp index 9fa3c809..ad1233bd 100644 --- a/src/basicio.cpp +++ b/src/basicio.cpp @@ -1093,11 +1093,16 @@ namespace Exiv2 { void MemIo::Impl::reserve(long wcount) { long need = wcount + idx_; + long blockSize = 32*1024; // 32768 ` + long maxBlockSize = 4*1024*1024; if (!isMalloced_) { - // Minimum size for 1st block is 32kB - long size = EXV_MAX(32768 * (1 + need / 32768), size_); + // Minimum size for 1st block + long size = EXV_MAX(blockSize * (1 + need / blockSize), size_); byte* data = (byte*)std::malloc(size); + if ( data == NULL ) { + throw Error(60); + } std::memcpy(data, data_, size_); data_ = data; sizeAlloced_ = size; @@ -1106,9 +1111,14 @@ namespace Exiv2 { if (need > size_) { if (need > sizeAlloced_) { - // Allocate in blocks of 32kB - long want = 32768 * (1 + need / 32768); + blockSize = 2*sizeAlloced_ ; + if ( blockSize > maxBlockSize ) blockSize = maxBlockSize ; + // Allocate in blocks + long want = blockSize * (1 + need / blockSize ); data_ = (byte*)std::realloc(data_, want); + if ( data_ == NULL ) { + throw Error(60); + } sizeAlloced_ = want; isMalloced_ = true; } diff --git a/src/error.cpp b/src/error.cpp index 4e16e1b6..1a6fa7bd 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -106,6 +106,7 @@ namespace { { 57, N_("invalid memory allocation request") }, { 58, N_("corrupted image metadata") }, { 59, N_("Arithmetic operation overflow") }, + { 60, N_("Memory allocation failed") }, }; } diff --git a/src/pentaxmn_int.cpp b/src/pentaxmn_int.cpp index 942865d8..88b62b72 100644 --- a/src/pentaxmn_int.cpp +++ b/src/pentaxmn_int.cpp @@ -1251,6 +1251,7 @@ namespace Exiv2 { unsigned long lensID = 0x3ff; unsigned long index = 0; + // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Pentax.html#LensData const ExifData::const_iterator lensInfo = metadata->findKey(ExifKey("Exif.PentaxDng.LensInfo")) != metadata->end() ? metadata->findKey(ExifKey("Exif.PentaxDng.LensInfo")) : metadata->findKey(ExifKey("Exif.Pentax.LensInfo")) @@ -1265,8 +1266,6 @@ namespace Exiv2 { // 0x0207 Pentax LensInfo Undefined 36 3 255 0 0 40 148 71 152 80 6 241 65 237 153 88 36 1 76 107 251 255 255 255 0 0 80 6 241 0 0 0 0 0 0 0 0 unsigned long base = 1; - // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Pentax.html#LensData - const ExifData::const_iterator lensInfo = metadata->findKey(ExifKey("Exif.Pentax.LensInfo")); unsigned int autoAperture = lensInfo->toLong(base+1) & 0x01 ; unsigned int minAperture = lensInfo->toLong(base+2) & 0x06 ; unsigned int minFocusDistance = lensInfo->toLong(base+3) & 0xf8 ; diff --git a/src/pngchunk_int.cpp b/src/pngchunk_int.cpp index 57c9f62b..19f5d9b7 100644 --- a/src/pngchunk_int.cpp +++ b/src/pngchunk_int.cpp @@ -103,15 +103,17 @@ namespace Exiv2 { { // From a tEXt, zTXt, or iTXt chunk, // we get the key, it's a null terminated string at the chunk start - if (data.size_ <= (stripHeader ? 8 : 0)) throw Error(14); - const byte *key = data.pData_ + (stripHeader ? 8 : 0); + const int offset = stripHeader ? 8 : 0; + if (data.size_ <= offset) throw Error(14); + const byte *key = data.pData_ + offset; // Find null string at end of key. int keysize=0; - for ( ; key[keysize] != 0 ; keysize++) + while (key[keysize] != 0) { + keysize++; // look if keysize is valid. - if (keysize >= data.size_) + if (keysize+offset >= data.size_) throw Error(14); } diff --git a/test/data/IMGP0020.exv b/test/data/IMGP0020.exv new file mode 100644 index 00000000..470b75f4 Binary files /dev/null and b/test/data/IMGP0020.exv differ diff --git a/test/data/issue_187 b/test/data/issue_187 new file mode 100644 index 00000000..3e05cc9e Binary files /dev/null and b/test/data/issue_187 differ diff --git a/tests/bugfixes/github/test_CVE_2017_17669.py b/tests/bugfixes/github/test_CVE_2017_17669.py new file mode 100644 index 00000000..803bb92a --- /dev/null +++ b/tests/bugfixes/github/test_CVE_2017_17669.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + +import system_tests + + +class RunPocFile(system_tests.Case): + + filename = "{data_path}/issue_187" + commands = ["{exiv2} " + filename] + retval = [1] + stdout = [""] + stderr = [ + """{exiv2_exception_msg} """ + filename + """: +{error_14_message} +""" + ] diff --git a/tests/bugfixes/github/test_regression_issue_201.py b/tests/bugfixes/github/test_regression_issue_201.py new file mode 100644 index 00000000..f203619f --- /dev/null +++ b/tests/bugfixes/github/test_regression_issue_201.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +import system_tests + + +class ShadowingError(system_tests.Case): + + commands = ["{exiv2} -PE {data_path}/IMGP0020.exv"] + stdout = [""] + stderr = [""] + retval = [0] + + def compare_stdout(self, i, command, got_stdout, expected_stdout): + """ + We only really care about the LensInfo line and that exiv2 does not + crash, which the return value check also ensures. + """ + self.assertIn( + "Exif.PentaxDng.LensInfo Undefined 69 131 0 0 255 0 40 148 111 65 69 6 238 65 78 153 80 40 1 73 107 251 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + got_stdout + ) diff --git a/tests/suite.conf b/tests/suite.conf index d143f780..134b1471 100644 --- a/tests/suite.conf +++ b/tests/suite.conf @@ -15,6 +15,7 @@ data_path: ../test/data tiff-test: ${ENV:exiv2_path}/tiff-test${ENV:binary_extension} [variables] +error_14_message: Failed to read image data error_58_message: corrupted image metadata error_57_message: invalid memory allocation request exiv2_exception_msg: Exiv2 exception in print action for file