aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@exmulti.com>2012-05-22 15:12:52 -0400
committerJeff Garzik <jgarzik@redhat.com>2012-05-22 15:12:52 -0400
commitf94b64c2f3a1994a21c4d99a1806d4f9611f810c (patch)
tree71565f3f86e1cedc0118242cd6d0899cecb32718
parentd1edab602a3ee729b308378d9d456f01e6933cfb (diff)
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.
-rw-r--r--src/db.cpp16
-rw-r--r--src/db.h9
2 files changed, 21 insertions, 4 deletions
diff --git a/src/db.cpp b/src/db.cpp
index a0b9dc20f7..5c169fe0ca 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -416,9 +416,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();
diff --git a/src/db.h b/src/db.h
index b8fc4db512..a67193b680 100644
--- 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());