changeset 2810:a2f7bc9841e0 draft

Prevent crashes due to missing or corrupted database records 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.
author Jeff Garzik <jgarzik@exmulti.com>
date Tue, 22 May 2012 15:12:52 -0400
parents caa08770229d
children 6eafb872571b
files src/db.cpp src/db.h
diffstat 2 files changed, 21 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -411,9 +411,15 @@
         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 @@
             return false;
 
         // Unserialize
+
+        try {
         string strType;
         ssKey >> strType;
         if (strType == "blockindex" && !fRequestShutdown)
@@ -564,6 +572,10 @@
         {
             break; // if shutdown requested or finished loading block index
         }
+        }    // try
+        catch (std::exception &e) {
+            return error("%s() : deserialize error", __PRETTY_FUNCTION__);
+        }
     }
     pcursor->close();
 
--- a/src/db.h
+++ b/src/db.h
@@ -72,8 +72,13 @@
             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());