diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2017-01-18 19:24:02 +0100 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2017-01-18 20:05:30 +0100 |
commit | 6012967c4746095e6f66a142cb9f639544c17377 (patch) | |
tree | 3388f969b65a5f9c3388bde027b6c6c08b1af6c8 /src | |
parent | b0b57a17306a7e963a4fe463f84e2b150a00a859 (diff) | |
parent | 82e8baab3caaadb1d923d1332c577fb91b9c5747 (diff) |
Merge #9512: Fix various things -fsanitize complains about
82e8baa Avoid boost dynamic_bitset in rest_getutxos (Pieter Wuille)
99f001e Fix memory leak in multiUserAuthorized (Pieter Wuille)
5a0b7e4 Fix memory leak in net_tests (Pieter Wuille)
6b03bfb Fix memory leak in wallet tests (Pieter Wuille)
f94f3e0 Avoid integer overflows in scriptnum tests (Pieter Wuille)
843c560 Avoid unaligned access in crypto i/o (Pieter Wuille)
Diffstat (limited to 'src')
-rw-r--r-- | src/crypto/common.h | 36 | ||||
-rw-r--r-- | src/httprpc.cpp | 4 | ||||
-rw-r--r-- | src/rest.cpp | 12 | ||||
-rw-r--r-- | src/test/net_tests.cpp | 4 | ||||
-rw-r--r-- | src/test/scriptnum_tests.cpp | 6 | ||||
-rw-r--r-- | src/wallet/test/wallet_tests.cpp | 12 |
6 files changed, 49 insertions, 25 deletions
diff --git a/src/crypto/common.h b/src/crypto/common.h index 580c72f5a6..4a9d1150b6 100644 --- a/src/crypto/common.h +++ b/src/crypto/common.h @@ -10,57 +10,73 @@ #endif #include <stdint.h> +#include <string.h> #include "compat/endian.h" uint16_t static inline ReadLE16(const unsigned char* ptr) { - return le16toh(*((uint16_t*)ptr)); + uint16_t x; + memcpy((char*)&x, ptr, 2); + return le16toh(x); } uint32_t static inline ReadLE32(const unsigned char* ptr) { - return le32toh(*((uint32_t*)ptr)); + uint32_t x; + memcpy((char*)&x, ptr, 4); + return le32toh(x); } uint64_t static inline ReadLE64(const unsigned char* ptr) { - return le64toh(*((uint64_t*)ptr)); + uint64_t x; + memcpy((char*)&x, ptr, 8); + return le64toh(x); } void static inline WriteLE16(unsigned char* ptr, uint16_t x) { - *((uint16_t*)ptr) = htole16(x); + uint16_t v = htole16(x); + memcpy(ptr, (char*)&v, 2); } void static inline WriteLE32(unsigned char* ptr, uint32_t x) { - *((uint32_t*)ptr) = htole32(x); + uint32_t v = htole32(x); + memcpy(ptr, (char*)&v, 4); } void static inline WriteLE64(unsigned char* ptr, uint64_t x) { - *((uint64_t*)ptr) = htole64(x); + uint64_t v = htole64(x); + memcpy(ptr, (char*)&v, 8); } uint32_t static inline ReadBE32(const unsigned char* ptr) { - return be32toh(*((uint32_t*)ptr)); + uint32_t x; + memcpy((char*)&x, ptr, 4); + return be32toh(x); } uint64_t static inline ReadBE64(const unsigned char* ptr) { - return be64toh(*((uint64_t*)ptr)); + uint64_t x; + memcpy((char*)&x, ptr, 8); + return be64toh(x); } void static inline WriteBE32(unsigned char* ptr, uint32_t x) { - *((uint32_t*)ptr) = htobe32(x); + uint32_t v = htobe32(x); + memcpy(ptr, (char*)&v, 4); } void static inline WriteBE64(unsigned char* ptr, uint64_t x) { - *((uint64_t*)ptr) = htobe64(x); + uint64_t v = htobe64(x); + memcpy(ptr, (char*)&v, 8); } #endif // BITCOIN_CRYPTO_COMMON_H diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 742ff2b8fb..93beda09a4 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -113,8 +113,8 @@ static bool multiUserAuthorized(std::string strUserPass) std::string strHash = vFields[2]; unsigned int KEY_SIZE = 32; - unsigned char *out = new unsigned char[KEY_SIZE]; - + unsigned char out[KEY_SIZE]; + CHMAC_SHA256(reinterpret_cast<const unsigned char*>(strSalt.c_str()), strSalt.size()).Write(reinterpret_cast<const unsigned char*>(strPass.c_str()), strPass.size()).Finalize(out); std::vector<unsigned char> hexvec(out, out+KEY_SIZE); std::string strHashFromPass = HexStr(hexvec); diff --git a/src/rest.cpp b/src/rest.cpp index 8a7c985e72..a8f8e753c6 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -17,7 +17,6 @@ #include "version.h" #include <boost/algorithm/string.hpp> -#include <boost/dynamic_bitset.hpp> #include <univalue.h> @@ -502,7 +501,8 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) vector<unsigned char> bitmap; vector<CCoin> outs; std::string bitmapStringRepresentation; - boost::dynamic_bitset<unsigned char> hits(vOutPoints.size()); + std::vector<bool> hits; + bitmap.resize((vOutPoints.size() + 7) / 8); { LOCK2(cs_main, mempool.cs); @@ -518,10 +518,11 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) for (size_t i = 0; i < vOutPoints.size(); i++) { CCoins coins; uint256 hash = vOutPoints[i].hash; + bool hit = false; if (view.GetCoins(hash, coins)) { mempool.pruneSpent(hash, coins); if (coins.IsAvailable(vOutPoints[i].n)) { - hits[i] = true; + hit = true; // Safe to index into vout here because IsAvailable checked if it's off the end of the array, or if // n is valid but points to an already spent output (IsNull). CCoin coin; @@ -533,10 +534,11 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) } } - bitmapStringRepresentation.append(hits[i] ? "1" : "0"); // form a binary string representation (human-readable for json output) + hits.push_back(hit); + bitmapStringRepresentation.append(hit ? "1" : "0"); // form a binary string representation (human-readable for json output) + bitmap[i / 8] |= ((uint8_t)hit) << (i % 8); } } - boost::to_block_range(hits, std::back_inserter(bitmap)); switch (rf) { case RF_BINARY: { diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 0bd7869f32..b9ed4952bb 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -162,12 +162,12 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test) bool fInboundIn = false; // Test that fFeeler is false by default. - CNode* pnode1 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, 0, pszDest, fInboundIn); + std::unique_ptr<CNode> pnode1(new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, 0, pszDest, fInboundIn)); BOOST_CHECK(pnode1->fInbound == false); BOOST_CHECK(pnode1->fFeeler == false); fInboundIn = true; - CNode* pnode2 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, pszDest, fInboundIn); + std::unique_ptr<CNode> pnode2(new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, pszDest, fInboundIn)); BOOST_CHECK(pnode2->fInbound == true); BOOST_CHECK(pnode2->fFeeler == false); } diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp index 6b6689c7d3..1d5893bdc3 100644 --- a/src/test/scriptnum_tests.cpp +++ b/src/test/scriptnum_tests.cpp @@ -12,8 +12,10 @@ BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup) -static const int64_t values[] = \ -{ 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX, LONG_MIN, LONG_MAX }; +/** A selection of numbers that do not trigger int64_t overflow + * when added/subtracted. */ +static const int64_t values[] = { 0, 1, -2, 127, 128, -255, 256, (1LL << 15) - 1, -(1LL << 16), (1LL << 24) - 1, (1LL << 31), 1 - (1LL << 32), 1LL << 40 }; + static const int64_t offsets[] = { 1, 0x79, 0x80, 0x81, 0xFF, 0x7FFF, 0x8000, 0xFFFF, 0x10000}; static bool verify(const CScriptNum10& bignum, const CScriptNum& scriptnum) diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index c7ce6fd243..ca086c86a8 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -23,6 +23,8 @@ using namespace std; +std::vector<std::unique_ptr<CWalletTx>> wtxn; + typedef set<pair<const CWalletTx*,unsigned int> > CoinSet; BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup) @@ -42,21 +44,21 @@ static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = fa // so stop vin being empty, and cache a non-zero Debit to fake out IsFromMe() tx.vin.resize(1); } - CWalletTx* wtx = new CWalletTx(&wallet, MakeTransactionRef(std::move(tx))); + std::unique_ptr<CWalletTx> wtx(new CWalletTx(&wallet, MakeTransactionRef(std::move(tx)))); if (fIsFromMe) { wtx->fDebitCached = true; wtx->nDebitCached = 1; } - COutput output(wtx, nInput, nAge, true, true); + COutput output(wtx.get(), nInput, nAge, true, true); vCoins.push_back(output); + wtxn.emplace_back(std::move(wtx)); } static void empty_wallet(void) { - BOOST_FOREACH(COutput output, vCoins) - delete output.tx; vCoins.clear(); + wtxn.clear(); } static bool equal_sets(CoinSet a, CoinSet b) @@ -349,6 +351,8 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset) BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); + + empty_wallet(); } BOOST_AUTO_TEST_SUITE_END() |