Prevent crashes due to missing or corrupted database records
authorJeff Garzik <jgarzik@exmulti.com>
Tue, 22 May 2012 19:12:52 +0000 (15:12 -0400)
committerGavin Andresen <gavinandresen@gmail.com>
Tue, 19 Jun 2012 19:36:43 +0000 (15:36 -0400)
Any problems seen during deserialization will throw an uncaught
exception, crashing the entire bitcoin process.  Properly return an
error instead, so that we may at least log the error and gracefully
shutdown other portions of the app.

src/db.cpp
src/db.h

index ef45976..f9151f7 100644 (file)
@@ -411,9 +411,15 @@ bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>&
         string strType;
         uint160 hashItem;
         CDiskTxPos pos;
-        ssKey >> strType >> hashItem >> pos;
         int nItemHeight;
-        ssValue >> nItemHeight;
+
+        try {
+            ssKey >> strType >> hashItem >> pos;
+            ssValue >> nItemHeight;
+        }
+        catch (std::exception &e) {
+            return error("%s() : deserialize error", __PRETTY_FUNCTION__);
+        }
 
         // Read transaction
         if (strType != "owner" || hashItem != hash160)
@@ -533,6 +539,8 @@ bool CTxDB::LoadBlockIndex()
             return false;
 
         // Unserialize
+
+        try {
         string strType;
         ssKey >> strType;
         if (strType == "blockindex" && !fRequestShutdown)
@@ -564,6 +572,10 @@ bool CTxDB::LoadBlockIndex()
         {
             break; // if shutdown requested or finished loading block index
         }
+        }    // try
+        catch (std::exception &e) {
+            return error("%s() : deserialize error", __PRETTY_FUNCTION__);
+        }
     }
     pcursor->close();
 
index 399b62f..dc795d2 100644 (file)
--- a/src/db.h
+++ b/src/db.h
@@ -72,8 +72,13 @@ protected:
             return false;
 
         // Unserialize value
-        CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION);
-        ssValue >> value;
+        try {
+            CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION);
+            ssValue >> value;
+        }
+        catch (std::exception &e) {
+            return false;
+        }
 
         // Clear and free memory
         memset(datValue.get_data(), 0, datValue.get_size());