diff --git a/include/exiv2/value.hpp b/include/exiv2/value.hpp index 64a8ca7..4e9f285 100644 --- a/include/exiv2/value.hpp +++ b/include/exiv2/value.hpp @@ -1658,11 +1658,13 @@ namespace Exiv2 { ok_ = true; return static_cast(value_[n]); } +// #55 crash when value_[n].first == LONG_MIN +#define LARGE_INT 1000000 // Specialization for rational template<> inline long ValueType::toLong(long n) const { - ok_ = (value_[n].second != 0); + ok_ = (value_[n].second != 0 && -LARGE_INT < value_[n].first && value_[n].first < LARGE_INT); if (!ok_) return 0; return value_[n].first / value_[n].second; } @@ -1670,7 +1672,7 @@ namespace Exiv2 { template<> inline long ValueType::toLong(long n) const { - ok_ = (value_[n].second != 0); + ok_ = (value_[n].second != 0 && value_[n].first < LARGE_INT); if (!ok_) return 0; return value_[n].first / value_[n].second; } diff --git a/src/basicio.cpp b/src/basicio.cpp index 1ede931..eac756f 100644 --- a/src/basicio.cpp +++ b/src/basicio.cpp @@ -990,6 +990,7 @@ namespace Exiv2 { DataBuf FileIo::read(long rcount) { assert(p_->fp_ != 0); + if ( (size_t) rcount > size() ) throw Error(57); DataBuf buf(rcount); long readCount = read(buf.pData_, buf.size_); buf.size_ = readCount; diff --git a/src/image.cpp b/src/image.cpp index 31b9b81..eeb1f37 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -399,7 +399,13 @@ namespace Exiv2 { ; // if ( offset > io.size() ) offset = 0; // Denial of service? - DataBuf buf(size*count + pad+20); // allocate a buffer + + // #55 memory allocation crash test/data/POC8 + long long allocate = (long long) size*count + pad+20; + if ( allocate > (long long) io.size() ) { + throw Error(57); + } + DataBuf buf(allocate); // allocate a buffer std::memcpy(buf.pData_,dir.pData_+8,4); // copy dir[8:11] into buffer (short strings) if ( count*size > 4 ) { // read into buffer size_t restore = io.tell(); // save