#534: Prevent integer overflow.

v0.27.3
Andreas Huggel 18 years ago
parent 4b95b20db8
commit 1e6db63ae9

@ -212,10 +212,12 @@ namespace Exiv2 {
ExifData::const_iterator sizes; ExifData::const_iterator sizes;
ExifKey key("Exif.Thumbnail.StripByteCounts"); ExifKey key("Exif.Thumbnail.StripByteCounts");
sizes = exifData.findKey(key); sizes = exifData.findKey(key);
if (sizes == exifData.end()) return 2; if (sizes == exifData.end()) return 1;
long totalSize = 0; uint32_t totalSize = 0;
for (long i = 0; i < sizes->count(); ++i) { for (long i = 0; i < sizes->count(); ++i) {
uint32_t size = sizes->toLong(i);
if (size > 0xffffffff - totalSize) return 1;
totalSize += sizes->toLong(i); totalSize += sizes->toLong(i);
} }
DataBuf stripsBuf(totalSize); DataBuf stripsBuf(totalSize);
@ -225,21 +227,23 @@ namespace Exiv2 {
ExifData::iterator stripOffsets; ExifData::iterator stripOffsets;
key = ExifKey("Exif.Thumbnail.StripOffsets"); key = ExifKey("Exif.Thumbnail.StripOffsets");
stripOffsets = exifData.findKey(key); stripOffsets = exifData.findKey(key);
if (stripOffsets == exifData.end()) return 2; if (stripOffsets == exifData.end()) return 1;
if (stripOffsets->count() != sizes->count()) return 2; if (stripOffsets->count() != sizes->count()) return 1;
std::ostringstream os; // for the strip offsets std::ostringstream os; // for the strip offsets
long currentOffset = 0; uint32_t currentOffset = 0;
long firstOffset = stripOffsets->toLong(0); uint32_t firstOffset = stripOffsets->toLong(0);
long lastOffset = 0; uint32_t lastOffset = 0;
long lastSize = 0; uint32_t lastSize = 0;
for (long i = 0; i < stripOffsets->count(); ++i) { for (long i = 0; i < stripOffsets->count(); ++i) {
long offset = stripOffsets->toLong(i); uint32_t offset = stripOffsets->toLong(i);
lastOffset = offset; lastOffset = offset;
long size = sizes->toLong(i); uint32_t size = sizes->toLong(i);
lastSize = size; lastSize = size;
if (len < offset + size) return 1; if ( size > 0xffffffff - offset
|| static_cast<uint32_t>(len) < offset + size) {
return 2;
}
std::memcpy(stripsBuf.pData_ + currentOffset, buf + offset, size); std::memcpy(stripsBuf.pData_ + currentOffset, buf + offset, size);
os << currentOffset << " "; os << currentOffset << " ";
currentOffset += size; currentOffset += size;
@ -300,12 +304,15 @@ namespace Exiv2 {
ExifKey key("Exif.Thumbnail.JPEGInterchangeFormat"); ExifKey key("Exif.Thumbnail.JPEGInterchangeFormat");
ExifData::iterator format = exifData.findKey(key); ExifData::iterator format = exifData.findKey(key);
if (format == exifData.end()) return 1; if (format == exifData.end()) return 1;
long offset = format->toLong(); uint32_t offset = format->toLong();
key = ExifKey("Exif.Thumbnail.JPEGInterchangeFormatLength"); key = ExifKey("Exif.Thumbnail.JPEGInterchangeFormatLength");
ExifData::const_iterator length = exifData.findKey(key); ExifData::const_iterator length = exifData.findKey(key);
if (length == exifData.end()) return 1; if (length == exifData.end()) return 1;
long size = length->toLong(); uint32_t size = length->toLong();
if (len < offset + size) return 2; if ( size > 0xffffffff - offset
|| static_cast<uint32_t>(len) < offset + size) {
return 2;
}
format->setDataArea(buf + offset, size); format->setDataArea(buf + offset, size);
format->setValue("0"); format->setValue("0");
if (pIfd1) { if (pIfd1) {
@ -592,8 +599,14 @@ namespace Exiv2 {
if (pIopIfd_) add(pIopIfd_->begin(), pIopIfd_->end(), byteOrder()); if (pIopIfd_) add(pIopIfd_->begin(), pIopIfd_->end(), byteOrder());
if (pGpsIfd_) add(pGpsIfd_->begin(), pGpsIfd_->end(), byteOrder()); if (pGpsIfd_) add(pGpsIfd_->begin(), pGpsIfd_->end(), byteOrder());
if (pIfd1_) add(pIfd1_->begin(), pIfd1_->end(), byteOrder()); if (pIfd1_) add(pIfd1_->begin(), pIfd1_->end(), byteOrder());
// Read the thumbnail (but don't worry whether it was successful or not) // Finally, read the thumbnail
readThumbnail(); rc = readThumbnail();
if (0 < rc) {
#ifndef SUPPRESS_WARNINGS
std::cerr << "Warning: Failed to read thumbnail, rc = "
<< rc << "\n";
#endif
}
return 0; return 0;
} // ExifData::load } // ExifData::load

Loading…
Cancel
Save