diff --git a/src/webpimage.cpp b/src/webpimage.cpp index b880d57f..11311e01 100644 --- a/src/webpimage.cpp +++ b/src/webpimage.cpp @@ -546,7 +546,7 @@ namespace Exiv2 { const uint32_t size_u32 = Exiv2::getULong(size_buff, littleEndian); // Check that `size_u32` is safe to cast to `long`. - enforce(size_u32 <= static_cast(std::numeric_limits::max()), + enforce(static_cast(size_u32) <= static_cast(std::numeric_limits::max()), Exiv2::kerCorruptedMetadata); const long size = static_cast(size_u32); @@ -671,27 +671,27 @@ namespace Exiv2 { offset += 12; } - const long sizePayload = payload.size_ + offset; - byte* rawExifData = new byte[sizePayload]; + const long sizePayload = Safe::add(payload.size_, offset); + DataBuf rawExifData(sizePayload); if (s_header) { us2Data(size_buff2, static_cast(sizePayload - 6), bigEndian); - memcpy(rawExifData, reinterpret_cast(&exifLongHeader), 4); - memcpy(rawExifData + 4, reinterpret_cast(&size_buff2), 2); + memcpy(rawExifData.pData_, reinterpret_cast(&exifLongHeader), 4); + memcpy(rawExifData.pData_ + 4, reinterpret_cast(&size_buff2), 2); } if (be_header || le_header) { us2Data(size_buff2, static_cast(sizePayload - 6), bigEndian); - memcpy(rawExifData, reinterpret_cast(&exifLongHeader), 4); - memcpy(rawExifData + 4, reinterpret_cast(&size_buff2), 2); - memcpy(rawExifData + 6, reinterpret_cast(&exifShortHeader), 6); + memcpy(rawExifData.pData_, reinterpret_cast(&exifLongHeader), 4); + memcpy(rawExifData.pData_ + 4, reinterpret_cast(&size_buff2), 2); + memcpy(rawExifData.pData_ + 6, reinterpret_cast(&exifShortHeader), 6); } - memcpy(rawExifData + offset, payload.pData_, payload.size_); + memcpy(rawExifData.pData_ + offset, payload.pData_, payload.size_); #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Display Hex Dump [size:" << static_cast(sizePayload) << "]" << std::endl; - std::cout << Internal::binaryToHex(rawExifData, sizePayload); + std::cout << Internal::binaryToHex(rawExifData.pData_, sizePayload); #endif if (pos != -1) { @@ -708,8 +708,6 @@ namespace Exiv2 { #endif exifData_.clear(); } - - delete [] rawExifData; } else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_XMP)) { readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata); xmpPacket_.assign(reinterpret_cast(payload.pData_), payload.size_); diff --git a/test/data/issue_1841_poc.webp b/test/data/issue_1841_poc.webp new file mode 100644 index 00000000..1ea6e538 Binary files /dev/null and b/test/data/issue_1841_poc.webp differ diff --git a/tests/bugfixes/github/test_issue_1841.py b/tests/bugfixes/github/test_issue_1841.py new file mode 100644 index 00000000..64640ebf --- /dev/null +++ b/tests/bugfixes/github/test_issue_1841.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +from system_tests import CaseMeta, path + +class MemoryLeakWebPImageDecodeChunks(metaclass=CaseMeta): + """ + Test for the bug described in: + https://github.com/Exiv2/exiv2/issues/1841 + """ + url = "https://github.com/Exiv2/exiv2/issues/1841" + + filename = path("$data_path/issue_1841_poc.webp") + commands = ["$exiv2 $filename"] + stdout = [""] + stderr = ["""$exiv2_exception_message $filename: +This does not look like a TIFF image +"""] + retval = [1]