From 0aadc11fd88b298c7af2dfb69763b2c67dc6b7b0 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 7 Jul 2017 00:54:42 -0700 Subject: [PATCH] Avoid dereference-of-casted-pointer --- src/core_memusage.h | 2 +- src/primitives/transaction.h | 4 ++-- src/rpc/blockchain.cpp | 2 +- src/script/interpreter.cpp | 4 ++-- src/script/script.h | 8 ++++++++ src/test/dbwrapper_tests.cpp | 6 +++--- src/txdb.cpp | 2 +- src/wallet/walletdb.cpp | 16 ++++++++-------- 8 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/core_memusage.h b/src/core_memusage.h index e4ccd54c4..f038e7b15 100644 --- a/src/core_memusage.h +++ b/src/core_memusage.h @@ -10,7 +10,7 @@ #include "memusage.h" static inline size_t RecursiveDynamicUsage(const CScript& script) { - return memusage::DynamicUsage(*static_cast(&script)); + return memusage::DynamicUsage(script); } static inline size_t RecursiveDynamicUsage(const COutPoint& out) { diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 00ac0b92b..f1b5e5937 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -107,7 +107,7 @@ public: template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(prevout); - READWRITE(*(CScriptBase*)(&scriptSig)); + READWRITE(scriptSig); READWRITE(nSequence); } @@ -147,7 +147,7 @@ public: template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(nValue); - READWRITE(*(CScriptBase*)(&scriptPubKey)); + READWRITE(scriptPubKey); } void SetNull() diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index c17ca2fa3..6178a1c7a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -798,7 +798,7 @@ static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, stats.nTransactions++; for (const auto output : outputs) { ss << VARINT(output.first + 1); - ss << *(const CScriptBase*)(&output.second.out.scriptPubKey); + ss << output.second.out.scriptPubKey; ss << VARINT(output.second.out.nValue); stats.nTransactionOutputs++; stats.nTotalAmount += output.second.out.nValue; diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 7149c938f..8a121774a 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1099,7 +1099,7 @@ public: // Serialize the script if (nInput != nIn) // Blank out other inputs' signatures - ::Serialize(s, CScriptBase()); + ::Serialize(s, CScript()); else SerializeScriptCode(s); // Serialize the nSequence @@ -1207,7 +1207,7 @@ uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsig // The prevout may already be contained in hashPrevout, and the nSequence // may already be contain in hashSequence. ss << txTo.vin[nIn].prevout; - ss << static_cast(scriptCode); + ss << scriptCode; ss << amount; ss << txTo.vin[nIn].nSequence; // Outputs (none/one/all, depending on flags) diff --git a/src/script/script.h b/src/script/script.h index bbb37f049..d16bfd0e0 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -8,6 +8,7 @@ #include "crypto/common.h" #include "prevector.h" +#include "serialize.h" #include #include @@ -404,6 +405,13 @@ public: CScript(std::vector::const_iterator pbegin, std::vector::const_iterator pend) : CScriptBase(pbegin, pend) { } CScript(const unsigned char* pbegin, const unsigned char* pend) : CScriptBase(pbegin, pend) { } + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(static_cast(*this)); + } + CScript& operator+=(const CScript& b) { insert(end(), b.begin(), b.end()); diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index be631ce7a..093509e61 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator) uint256 in2 = InsecureRand256(); BOOST_CHECK(dbw.Write(key2, in2)); - std::unique_ptr it(const_cast(&dbw)->NewIterator()); + std::unique_ptr it(const_cast(dbw).NewIterator()); // Be sure to seek past the obfuscation key (if it exists) it->Seek(key); @@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(iterator_ordering) BOOST_CHECK(dbw.Write(key, value)); } - std::unique_ptr it(const_cast(&dbw)->NewIterator()); + std::unique_ptr it(const_cast(dbw).NewIterator()); for (int c=0; c<2; ++c) { int seek_start; if (c == 0) @@ -286,7 +286,7 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering) } } - std::unique_ptr it(const_cast(&dbw)->NewIterator()); + std::unique_ptr it(const_cast(dbw).NewIterator()); for (int c=0; c<2; ++c) { int seek_start; if (c == 0) diff --git a/src/txdb.cpp b/src/txdb.cpp index 002f6550b..aa0b73a41 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -172,7 +172,7 @@ bool CBlockTreeDB::ReadLastBlockFile(int &nFile) { CCoinsViewCursor *CCoinsViewDB::Cursor() const { - CCoinsViewDBCursor *i = new CCoinsViewDBCursor(const_cast(&db)->NewIterator(), GetBestBlock()); + CCoinsViewDBCursor *i = new CCoinsViewDBCursor(const_cast(db).NewIterator(), GetBestBlock()); /* It seems that there are no "const iterators" for LevelDB. Since we only need read operations on it, use a const-cast to get around that restriction. */ diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index deb09a477..d2072f6e7 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -94,23 +94,23 @@ bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey) bool CWalletDB::WriteCScript(const uint160& hash, const CScript& redeemScript) { - return WriteIC(std::make_pair(std::string("cscript"), hash), *(const CScriptBase*)(&redeemScript), false); + return WriteIC(std::make_pair(std::string("cscript"), hash), redeemScript, false); } bool CWalletDB::WriteWatchOnly(const CScript &dest, const CKeyMetadata& keyMeta) { - if (!WriteIC(std::make_pair(std::string("watchmeta"), *(const CScriptBase*)(&dest)), keyMeta)) { + if (!WriteIC(std::make_pair(std::string("watchmeta"), dest), keyMeta)) { return false; } - return WriteIC(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest)), '1'); + return WriteIC(std::make_pair(std::string("watchs"), dest), '1'); } bool CWalletDB::EraseWatchOnly(const CScript &dest) { - if (!EraseIC(std::make_pair(std::string("watchmeta"), *(const CScriptBase*)(&dest)))) { + if (!EraseIC(std::make_pair(std::string("watchmeta"), dest))) { return false; } - return EraseIC(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest))); + return EraseIC(std::make_pair(std::string("watchs"), dest)); } bool CWalletDB::WriteBestBlock(const CBlockLocator& locator) @@ -323,7 +323,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, { wss.nWatchKeys++; CScript script; - ssKey >> *(CScriptBase*)(&script); + ssKey >> script; char fYes; ssValue >> fYes; if (fYes == '1') @@ -440,7 +440,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, else if (strType == "watchmeta") { CScript script; - ssKey >> *(CScriptBase*)(&script); + ssKey >> script; keyID = CScriptID(script); } @@ -474,7 +474,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, uint160 hash; ssKey >> hash; CScript script; - ssValue >> *(CScriptBase*)(&script); + ssValue >> script; if (!pwallet->LoadCScript(script)) { strErr = "Error reading wallet database: LoadCScript failed";