117 lines
5.1 KiB
Diff
117 lines
5.1 KiB
Diff
From caa4e6745a76a23bb80127cf54c0d65096ae684c Mon Sep 17 00:00:00 2001
|
|
From: Kevin Backhouse <kev@semmle.com>
|
|
Date: Tue, 30 Apr 2019 09:26:18 +0100
|
|
Subject: [PATCH] Avoid negative integer overflow when `filesize <
|
|
io_->tell()`.
|
|
|
|
This fixes #791.
|
|
---
|
|
src/webpimage.cpp | 33 +++++++++++++++++++++------------
|
|
1 file changed, 21 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/src/webpimage.cpp b/src/webpimage.cpp
|
|
index 51a200b..9d7272c 100644
|
|
--- a/src/webpimage.cpp
|
|
+++ b/src/webpimage.cpp
|
|
@@ -67,6 +67,15 @@ namespace Exiv2 {
|
|
namespace Exiv2 {
|
|
using namespace Exiv2::Internal;
|
|
|
|
+ // This static function is a temporary fix in v0.27. In the next version,
|
|
+ // it will be added as a method of BasicIo.
|
|
+ static void readOrThrow(BasicIo& iIo, byte* buf, long rcount, ErrorCode err) {
|
|
+ const long nread = iIo.read(buf, rcount);
|
|
+ enforce(nread == rcount, err);
|
|
+ enforce(!iIo.error(), err);
|
|
+ }
|
|
+
|
|
+
|
|
WebPImage::WebPImage(BasicIo::AutoPtr io)
|
|
: Image(ImageType::webp, mdNone, io)
|
|
{
|
|
@@ -512,7 +521,7 @@ namespace Exiv2 {
|
|
DataBuf chunkId(5);
|
|
chunkId.pData_[4] = '\0' ;
|
|
|
|
- io_->readOrThrow(data, WEBP_TAG_SIZE * 3, Exiv2::kerCorruptedMetadata);
|
|
+ readOrThrow(*io_, data, WEBP_TAG_SIZE * 3, Exiv2::kerCorruptedMetadata);
|
|
|
|
const uint32_t filesize = Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian) + 8;
|
|
enforce(filesize <= io_->size(), Exiv2::kerCorruptedMetadata);
|
|
@@ -532,8 +541,8 @@ namespace Exiv2 {
|
|
|
|
chunkId.pData_[4] = '\0' ;
|
|
while ( !io_->eof() && (uint64_t) io_->tell() < filesize) {
|
|
- io_->readOrThrow(chunkId.pData_, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
|
- io_->readOrThrow(size_buff, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
|
+ readOrThrow(*io_, chunkId.pData_, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
|
+ readOrThrow(*io_, size_buff, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
|
const uint32_t size = Exiv2::getULong(size_buff, littleEndian);
|
|
enforce(io_->tell() <= filesize, Exiv2::kerCorruptedMetadata);
|
|
enforce(size <= (filesize - io_->tell()), Exiv2::kerCorruptedMetadata);
|
|
@@ -545,8 +554,8 @@ namespace Exiv2 {
|
|
|
|
has_canvas_data = true;
|
|
byte size_buf[WEBP_TAG_SIZE];
|
|
-
|
|
- io_->readOrThrow(payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
|
+
|
|
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
|
|
|
// Fetch width
|
|
memcpy(&size_buf, &payload.pData_[4], 3);
|
|
@@ -561,7 +570,7 @@ namespace Exiv2 {
|
|
enforce(size >= 10, Exiv2::kerCorruptedMetadata);
|
|
|
|
has_canvas_data = true;
|
|
- io_->readOrThrow(payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
|
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
|
byte size_buf[WEBP_TAG_SIZE];
|
|
|
|
// Fetch width""
|
|
@@ -582,7 +591,7 @@ namespace Exiv2 {
|
|
byte size_buf_w[2];
|
|
byte size_buf_h[3];
|
|
|
|
- io_->readOrThrow(payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
|
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
|
|
|
// Fetch width
|
|
memcpy(&size_buf_w, &payload.pData_[1], 2);
|
|
@@ -599,8 +608,8 @@ namespace Exiv2 {
|
|
|
|
has_canvas_data = true;
|
|
byte size_buf[WEBP_TAG_SIZE];
|
|
-
|
|
- io_->readOrThrow(payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
|
+
|
|
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
|
|
|
// Fetch width
|
|
memcpy(&size_buf, &payload.pData_[6], 3);
|
|
@@ -612,10 +621,10 @@ namespace Exiv2 {
|
|
size_buf[3] = 0;
|
|
pixelHeight_ = Exiv2::getULong(size_buf, littleEndian) + 1;
|
|
} else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ICCP)) {
|
|
- io_->readOrThrow(payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
|
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
|
this->setIccProfile(payload);
|
|
} else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_EXIF)) {
|
|
- io_->readOrThrow(payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
|
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
|
|
|
byte size_buff[2];
|
|
byte exifLongHeader[] = { 0xFF, 0x01, 0xFF, 0xE1 };
|
|
@@ -696,7 +705,7 @@ namespace Exiv2 {
|
|
|
|
if (rawExifData) free(rawExifData);
|
|
} else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_XMP)) {
|
|
- io_->readOrThrow(payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
|
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
|
xmpPacket_.assign(reinterpret_cast<char*>(payload.pData_), payload.size_);
|
|
if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_)) {
|
|
#ifndef SUPPRESS_WARNINGS
|
|
--
|
|
2.23.0
|
|
|