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 95589cd..f2e1518 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/error.cpp b/src/error.cpp index 80378c1..e90a9c0 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -106,6 +106,9 @@ namespace { { 52, N_("%1 has invalid XMP value type `%2'") }, // %1=key, %2=value type { 53, N_("Not a valid ICC Profile") }, { 54, N_("Not valid XMP") }, + { 55, N_("tiff directory length is too large") }, + { 56, N_("invalid type value detected in Image::printIFDStructure") }, + { 57, N_("invalid memory allocation request") }, }; } diff --git a/src/image.cpp b/src/image.cpp index 0d82804..ec5b873 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 diff --git a/test/bugfixes-test.sh b/test/bugfixes-test.sh index f91c675..c90ae55 100755 --- a/test/bugfixes-test.sh +++ b/test/bugfixes-test.sh @@ -602,6 +602,7 @@ source ./functions.source runTest exiv2 -pX $filename | xmllint --format - num=1231 + printf "$num " >&3 for X in a b; do filename=exiv2-bug$num$X.jpg echo '------>' Bug $filename '<-------' >&2 @@ -622,6 +623,7 @@ source ./functions.source runTest exiv2 -pa $filename num=1252 + printf "$num " >&3 for X in a b; do filename=exiv2-bug$num$X.exv echo '------>' Bug $filename '<-------' >&2 @@ -629,6 +631,13 @@ source ./functions.source runTest exiv2 -pa --grep lens/i $filename done + num=g55 + printf "$num " >&3 + filename=POC8 + echo '------>' Bug $filename '<-------' >&2 + copyTestFile $filename + runTest exiv2 $filename 2>/dev/null + ) 3>&1 > $results 2>&1 printf "\n"