c6f1e14
diff --git a/include/exiv2/value.hpp b/include/exiv2/value.hpp
c6f1e14
index 64a8ca7..4e9f285 100644
c6f1e14
--- a/include/exiv2/value.hpp
c6f1e14
+++ b/include/exiv2/value.hpp
c6f1e14
@@ -1658,11 +1658,13 @@ namespace Exiv2 {
c6f1e14
         ok_ = true;
c6f1e14
         return static_cast<long>(value_[n]);
c6f1e14
     }
c6f1e14
+// #55 crash when value_[n].first == LONG_MIN
c6f1e14
+#define LARGE_INT 1000000
c6f1e14
     // Specialization for rational
c6f1e14
     template<>
c6f1e14
     inline long ValueType<Rational>::toLong(long n) const
c6f1e14
     {
c6f1e14
-        ok_ = (value_[n].second != 0);
c6f1e14
+        ok_ = (value_[n].second != 0 && -LARGE_INT < value_[n].first && value_[n].first < LARGE_INT);
c6f1e14
         if (!ok_) return 0;
c6f1e14
         return value_[n].first / value_[n].second;
c6f1e14
     }
c6f1e14
@@ -1670,7 +1672,7 @@ namespace Exiv2 {
c6f1e14
     template<>
c6f1e14
     inline long ValueType<URational>::toLong(long n) const
c6f1e14
     {
c6f1e14
-        ok_ = (value_[n].second != 0);
c6f1e14
+        ok_ = (value_[n].second != 0 && value_[n].first < LARGE_INT);
c6f1e14
         if (!ok_) return 0;
c6f1e14
         return value_[n].first / value_[n].second;
c6f1e14
     }
c6f1e14
diff --git a/src/basicio.cpp b/src/basicio.cpp
c6f1e14
index 95589cd..f2e1518 100644
c6f1e14
--- a/src/basicio.cpp
c6f1e14
+++ b/src/basicio.cpp
c6f1e14
@@ -990,6 +990,7 @@ namespace Exiv2 {
c6f1e14
     DataBuf FileIo::read(long rcount)
c6f1e14
     {
c6f1e14
         assert(p_->fp_ != 0);
c6f1e14
+        if ( (size_t) rcount > size() ) throw Error(57);
c6f1e14
         DataBuf buf(rcount);
c6f1e14
         long readCount = read(buf.pData_, buf.size_);
c6f1e14
         buf.size_ = readCount;
c6f1e14
diff --git a/src/error.cpp b/src/error.cpp
c6f1e14
index 80378c1..e90a9c0 100644
c6f1e14
--- a/src/error.cpp
c6f1e14
+++ b/src/error.cpp
c6f1e14
@@ -106,6 +106,9 @@ namespace {
c6f1e14
         { 52, N_("%1 has invalid XMP value type `%2'") }, // %1=key, %2=value type
c6f1e14
         { 53, N_("Not a valid ICC Profile") },
c6f1e14
         { 54, N_("Not valid XMP") },
c6f1e14
+        { 55, N_("tiff directory length is too large") },
c6f1e14
+        { 56, N_("invalid type value detected in Image::printIFDStructure") },
c6f1e14
+        { 57, N_("invalid memory allocation request") },
c6f1e14
     };
c6f1e14
 
c6f1e14
 }
c6f1e14
diff --git a/src/image.cpp b/src/image.cpp
c6f1e14
index 0d82804..ec5b873 100644
c6f1e14
--- a/src/image.cpp
c6f1e14
+++ b/src/image.cpp
c6f1e14
@@ -399,7 +399,13 @@ namespace Exiv2 {
c6f1e14
                                 ;
c6f1e14
 
c6f1e14
                 // if ( offset > io.size() ) offset = 0; // Denial of service?
c6f1e14
-                DataBuf  buf(size*count + pad+20);  // allocate a buffer
c6f1e14
+
c6f1e14
+                // #55 memory allocation crash test/data/POC8
c6f1e14
+                long long allocate = (long long) (size*count + pad+20);
c6f1e14
+                if ( allocate > (long long) io.size() ) {
c6f1e14
+                    throw Error(57);
c6f1e14
+                }
c6f1e14
+                DataBuf  buf(allocate);  // allocate a buffer
c6f1e14
                 std::memcpy(buf.pData_,dir.pData_+8,4);  // copy dir[8:11] into buffer (short strings)
c6f1e14
                 if ( count*size > 4 ) {            // read into buffer
c6f1e14
                     size_t   restore = io.tell();  // save
c6f1e14
diff --git a/test/bugfixes-test.sh b/test/bugfixes-test.sh
c6f1e14
index f91c675..c90ae55 100755
c6f1e14
--- a/test/bugfixes-test.sh
c6f1e14
+++ b/test/bugfixes-test.sh
c6f1e14
@@ -602,6 +602,7 @@ source ./functions.source
c6f1e14
     runTest exiv2 -pX                   $filename | xmllint --format -
c6f1e14
 
c6f1e14
     num=1231
c6f1e14
+    printf "$num " >&3
c6f1e14
     for X in a b; do
c6f1e14
       filename=exiv2-bug$num$X.jpg
c6f1e14
       echo '------>' Bug $filename '<-------' >&2
c6f1e14
@@ -622,6 +623,7 @@ source ./functions.source
c6f1e14
     runTest exiv2 -pa                   $filename
c6f1e14
 
c6f1e14
     num=1252
c6f1e14
+    printf "$num " >&3
c6f1e14
     for X in a b; do
c6f1e14
       filename=exiv2-bug$num$X.exv
c6f1e14
       echo '------>' Bug $filename '<-------' >&2
c6f1e14
@@ -629,6 +631,13 @@ source ./functions.source
c6f1e14
       runTest exiv2 -pa --grep lens/i   $filename
c6f1e14
     done
c6f1e14
 
c6f1e14
+    num=g55
c6f1e14
+    printf "$num " >&3
c6f1e14
+    filename=POC8
c6f1e14
+    echo '------>' Bug $filename '<-------' >&2
c6f1e14
+    copyTestFile                      $filename
c6f1e14
+    runTest exiv2                     $filename 2>/dev/null
c6f1e14
+
c6f1e14
 ) 3>&1 > $results 2>&1
c6f1e14
 
c6f1e14
 printf "\n"