0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-04 13:55:23 -05:00

Merge bitcoin/bitcoin#28127: refactor: Remove C-style const-violating cast, Use reinterpret_cast

fa9108f85a refactor: Use reinterpret_cast where appropriate (MarcoFalke)
3333f950d4 refactor: Avoid casting away constness (MarcoFalke)
fa6394dd10 refactor: Remove unused C-style casts (MarcoFalke)

Pull request description:

  Using a C-style cast to convert pointer types to a byte-like pointer type has many issues:

  * It may accidentally and silently throw away `const`.
  * It forces reviewers to check that it doesn't accidentally throw away `const`.

  For example, on current master a `const char*` is cast to `unsigned char*` (without `const`), see d23fda0584/src/span.h (L273) . This can lead to UB, and the only reason why it didn't lead to UB is because the return type added back the `const`. (Obviously this would break if the return type was deduced via `auto`)

  Fix all issues by adding back the `const` and using `reinterpret_cast` where appropriate.

ACKs for top commit:
  darosior:
    re-utACK fa9108f85a
  hebasto:
    re-ACK fa9108f85a.
  john-moffett:
    ACK fa9108f85a

Tree-SHA512: 87f6e4b574f9bd96d4e0f2a0631fd0a9dc6096e5d4f1b95042fe9f197afc2fe9a24e333aeb34fed11feefcdb184a238fe1ea5aff10d580bb18d76bfe48b76a10
This commit is contained in:
fanquake 2023-07-26 15:47:41 +01:00
commit f57e724a80
No known key found for this signature in database
GPG key ID: 2EEB9F5CC09526C1
5 changed files with 55 additions and 53 deletions

View file

@ -17,73 +17,73 @@
uint16_t static inline ReadLE16(const unsigned char* ptr)
{
uint16_t x;
memcpy((char*)&x, ptr, 2);
memcpy(&x, ptr, 2);
return le16toh(x);
}
uint32_t static inline ReadLE32(const unsigned char* ptr)
{
uint32_t x;
memcpy((char*)&x, ptr, 4);
memcpy(&x, ptr, 4);
return le32toh(x);
}
uint64_t static inline ReadLE64(const unsigned char* ptr)
{
uint64_t x;
memcpy((char*)&x, ptr, 8);
memcpy(&x, ptr, 8);
return le64toh(x);
}
void static inline WriteLE16(unsigned char* ptr, uint16_t x)
{
uint16_t v = htole16(x);
memcpy(ptr, (char*)&v, 2);
memcpy(ptr, &v, 2);
}
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
{
uint32_t v = htole32(x);
memcpy(ptr, (char*)&v, 4);
memcpy(ptr, &v, 4);
}
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
{
uint64_t v = htole64(x);
memcpy(ptr, (char*)&v, 8);
memcpy(ptr, &v, 8);
}
uint16_t static inline ReadBE16(const unsigned char* ptr)
{
uint16_t x;
memcpy((char*)&x, ptr, 2);
memcpy(&x, ptr, 2);
return be16toh(x);
}
uint32_t static inline ReadBE32(const unsigned char* ptr)
{
uint32_t x;
memcpy((char*)&x, ptr, 4);
memcpy(&x, ptr, 4);
return be32toh(x);
}
uint64_t static inline ReadBE64(const unsigned char* ptr)
{
uint64_t x;
memcpy((char*)&x, ptr, 8);
memcpy(&x, ptr, 8);
return be64toh(x);
}
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
{
uint32_t v = htobe32(x);
memcpy(ptr, (char*)&v, 4);
memcpy(ptr, &v, 4);
}
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
{
uint64_t v = htobe64(x);
memcpy(ptr, (char*)&v, 8);
memcpy(ptr, &v, 8);
}
/** Return the smallest number n such that (x >> n) == 0 (or 64 if the highest bit in x is set. */

View file

@ -54,6 +54,8 @@ struct DBParams {
DBOptions options{};
};
inline auto CharCast(const std::byte* data) { return reinterpret_cast<const char*>(data); }
class dbwrapper_error : public std::runtime_error
{
public:
@ -113,12 +115,12 @@ public:
{
ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
ssKey << key;
leveldb::Slice slKey((const char*)ssKey.data(), ssKey.size());
leveldb::Slice slKey(CharCast(ssKey.data()), ssKey.size());
ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
ssValue << value;
ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent));
leveldb::Slice slValue((const char*)ssValue.data(), ssValue.size());
leveldb::Slice slValue(CharCast(ssValue.data()), ssValue.size());
batch.Put(slKey, slValue);
// LevelDB serializes writes as:
@ -138,7 +140,7 @@ public:
{
ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
ssKey << key;
leveldb::Slice slKey((const char*)ssKey.data(), ssKey.size());
leveldb::Slice slKey(CharCast(ssKey.data()), ssKey.size());
batch.Delete(slKey);
// LevelDB serializes erases as:
@ -177,7 +179,7 @@ public:
DataStream ssKey{};
ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
ssKey << key;
leveldb::Slice slKey((const char*)ssKey.data(), ssKey.size());
leveldb::Slice slKey(CharCast(ssKey.data()), ssKey.size());
piter->Seek(slKey);
}
@ -265,7 +267,7 @@ public:
DataStream ssKey{};
ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
ssKey << key;
leveldb::Slice slKey((const char*)ssKey.data(), ssKey.size());
leveldb::Slice slKey(CharCast(ssKey.data()), ssKey.size());
std::string strValue;
leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
@ -307,7 +309,7 @@ public:
DataStream ssKey{};
ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
ssKey << key;
leveldb::Slice slKey((const char*)ssKey.data(), ssKey.size());
leveldb::Slice slKey(CharCast(ssKey.data()), ssKey.size());
std::string strValue;
leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
@ -351,8 +353,8 @@ public:
ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
ssKey1 << key_begin;
ssKey2 << key_end;
leveldb::Slice slKey1((const char*)ssKey1.data(), ssKey1.size());
leveldb::Slice slKey2((const char*)ssKey2.data(), ssKey2.size());
leveldb::Slice slKey1(CharCast(ssKey1.data()), ssKey1.size());
leveldb::Slice slKey2(CharCast(ssKey2.data()), ssKey2.size());
uint64_t size = 0;
leveldb::Range range(slKey1, slKey2);
pdb->GetApproximateSizes(&range, 1, &size);

View file

@ -5,10 +5,10 @@
#ifndef BITCOIN_SPAN_H
#define BITCOIN_SPAN_H
#include <type_traits>
#include <cstddef>
#include <algorithm>
#include <assert.h>
#include <cassert>
#include <cstddef>
#include <type_traits>
#ifdef DEBUG
#define CONSTEXPR_IF_NOT_DEBUG
@ -267,10 +267,10 @@ Span<std::byte> MakeWritableByteSpan(V&& v) noexcept
}
// Helper functions to safely cast to unsigned char pointers.
inline unsigned char* UCharCast(char* c) { return (unsigned char*)c; }
inline unsigned char* UCharCast(char* c) { return reinterpret_cast<unsigned char*>(c); }
inline unsigned char* UCharCast(unsigned char* c) { return c; }
inline unsigned char* UCharCast(std::byte* c) { return (unsigned char*)c; }
inline const unsigned char* UCharCast(const char* c) { return (unsigned char*)c; }
inline unsigned char* UCharCast(std::byte* c) { return reinterpret_cast<unsigned char*>(c); }
inline const unsigned char* UCharCast(const char* c) { return reinterpret_cast<const unsigned char*>(c); }
inline const unsigned char* UCharCast(const unsigned char* c) { return c; }
inline const unsigned char* UCharCast(const std::byte* c) { return reinterpret_cast<const unsigned char*>(c); }

View file

@ -112,7 +112,7 @@ public:
test.SetupArgs({{"-value", flags}});
const char* argv[] = {"ignored", arg};
std::string error;
bool success = test.ParseParameters(arg ? 2 : 1, (char**)argv, error);
bool success = test.ParseParameters(arg ? 2 : 1, argv, error);
BOOST_CHECK_EQUAL(test.GetSetting("-value").write(), expect.setting.write());
auto settings_list = test.GetSettingsList("-value");
@ -217,13 +217,13 @@ BOOST_AUTO_TEST_CASE(util_ParseParameters)
std::string error;
LOCK(testArgs.cs_args);
testArgs.SetupArgs({a, b, ccc, d});
BOOST_CHECK(testArgs.ParseParameters(0, (char**)argv_test, error));
BOOST_CHECK(testArgs.ParseParameters(0, argv_test, error));
BOOST_CHECK(testArgs.m_settings.command_line_options.empty() && testArgs.m_settings.ro_config.empty());
BOOST_CHECK(testArgs.ParseParameters(1, (char**)argv_test, error));
BOOST_CHECK(testArgs.ParseParameters(1, argv_test, error));
BOOST_CHECK(testArgs.m_settings.command_line_options.empty() && testArgs.m_settings.ro_config.empty());
BOOST_CHECK(testArgs.ParseParameters(7, (char**)argv_test, error));
BOOST_CHECK(testArgs.ParseParameters(7, argv_test, error));
// expectation: -ignored is ignored (program name argument),
// -a, -b and -ccc end up in map, -d ignored because it is after
// a non-option argument (non-GNU option parsing)
@ -248,17 +248,17 @@ BOOST_AUTO_TEST_CASE(util_ParseInvalidParameters)
const char* argv[] = {"ignored", "-registered"};
std::string error;
BOOST_CHECK(test.ParseParameters(2, (char**)argv, error));
BOOST_CHECK(test.ParseParameters(2, argv, error));
BOOST_CHECK_EQUAL(error, "");
argv[1] = "-unregistered";
BOOST_CHECK(!test.ParseParameters(2, (char**)argv, error));
BOOST_CHECK(!test.ParseParameters(2, argv, error));
BOOST_CHECK_EQUAL(error, "Invalid parameter -unregistered");
// Make sure registered parameters prefixed with a chain type trigger errors.
// (Previously, they were accepted and ignored.)
argv[1] = "-test.registered";
BOOST_CHECK(!test.ParseParameters(2, (char**)argv, error));
BOOST_CHECK(!test.ParseParameters(2, argv, error));
BOOST_CHECK_EQUAL(error, "Invalid parameter -test.registered");
}
@ -269,7 +269,7 @@ static void TestParse(const std::string& str, bool expected_bool, int64_t expect
std::string arg = "-value=" + str;
const char* argv[] = {"ignored", arg.c_str()};
std::string error;
BOOST_CHECK(test.ParseParameters(2, (char**)argv, error));
BOOST_CHECK(test.ParseParameters(2, argv, error));
BOOST_CHECK_EQUAL(test.GetBoolArg("-value", false), expected_bool);
BOOST_CHECK_EQUAL(test.GetBoolArg("-value", true), expected_bool);
BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99998), expected_int);
@ -331,7 +331,7 @@ BOOST_AUTO_TEST_CASE(util_GetBoolArg)
std::string error;
LOCK(testArgs.cs_args);
testArgs.SetupArgs({a, b, c, d, e, f});
BOOST_CHECK(testArgs.ParseParameters(7, (char**)argv_test, error));
BOOST_CHECK(testArgs.ParseParameters(7, argv_test, error));
// Each letter should be set.
for (const char opt : "abcdef")
@ -368,7 +368,7 @@ BOOST_AUTO_TEST_CASE(util_GetBoolArgEdgeCases)
const char *argv_test[] = {"ignored", "-nofoo", "-foo", "-nobar=0"};
testArgs.SetupArgs({foo, bar});
std::string error;
BOOST_CHECK(testArgs.ParseParameters(4, (char**)argv_test, error));
BOOST_CHECK(testArgs.ParseParameters(4, argv_test, error));
// This was passed twice, second one overrides the negative setting.
BOOST_CHECK(!testArgs.IsArgNegated("-foo"));
@ -380,7 +380,7 @@ BOOST_AUTO_TEST_CASE(util_GetBoolArgEdgeCases)
// Config test
const char *conf_test = "nofoo=1\nfoo=1\nnobar=0\n";
BOOST_CHECK(testArgs.ParseParameters(1, (char**)argv_test, error));
BOOST_CHECK(testArgs.ParseParameters(1, argv_test, error));
testArgs.ReadConfigString(conf_test);
// This was passed twice, second one overrides the negative setting,
@ -395,7 +395,7 @@ BOOST_AUTO_TEST_CASE(util_GetBoolArgEdgeCases)
// Combined test
const char *combo_test_args[] = {"ignored", "-nofoo", "-bar"};
const char *combo_test_conf = "foo=1\nnobar=1\n";
BOOST_CHECK(testArgs.ParseParameters(3, (char**)combo_test_args, error));
BOOST_CHECK(testArgs.ParseParameters(3, combo_test_args, error));
testArgs.ReadConfigString(combo_test_conf);
// Command line overrides, but doesn't erase old setting
@ -655,38 +655,38 @@ BOOST_AUTO_TEST_CASE(util_GetChainTypeString)
const char* testnetconf = "testnet=1\nregtest=0\n[test]\nregtest=1";
std::string error;
BOOST_CHECK(test_args.ParseParameters(0, (char**)argv_testnet, error));
BOOST_CHECK(test_args.ParseParameters(0, argv_testnet, error));
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "main");
BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_testnet, error));
BOOST_CHECK(test_args.ParseParameters(2, argv_testnet, error));
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_regtest, error));
BOOST_CHECK(test_args.ParseParameters(2, argv_regtest, error));
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "regtest");
BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_test_no_reg, error));
BOOST_CHECK(test_args.ParseParameters(3, argv_test_no_reg, error));
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_both, error));
BOOST_CHECK(test_args.ParseParameters(3, argv_both, error));
BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
BOOST_CHECK(test_args.ParseParameters(0, (char**)argv_testnet, error));
BOOST_CHECK(test_args.ParseParameters(0, argv_testnet, error));
test_args.ReadConfigString(testnetconf);
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_testnet, error));
BOOST_CHECK(test_args.ParseParameters(2, argv_testnet, error));
test_args.ReadConfigString(testnetconf);
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_regtest, error));
BOOST_CHECK(test_args.ParseParameters(2, argv_regtest, error));
test_args.ReadConfigString(testnetconf);
BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_test_no_reg, error));
BOOST_CHECK(test_args.ParseParameters(3, argv_test_no_reg, error));
test_args.ReadConfigString(testnetconf);
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_both, error));
BOOST_CHECK(test_args.ParseParameters(3, argv_both, error));
test_args.ReadConfigString(testnetconf);
BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
@ -694,23 +694,23 @@ BOOST_AUTO_TEST_CASE(util_GetChainTypeString)
// [test] regtest=1 potentially relevant) doesn't break things
test_args.SelectConfigNetwork("test");
BOOST_CHECK(test_args.ParseParameters(0, (char**)argv_testnet, error));
BOOST_CHECK(test_args.ParseParameters(0, argv_testnet, error));
test_args.ReadConfigString(testnetconf);
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_testnet, error));
BOOST_CHECK(test_args.ParseParameters(2, argv_testnet, error));
test_args.ReadConfigString(testnetconf);
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_regtest, error));
BOOST_CHECK(test_args.ParseParameters(2, argv_regtest, error));
test_args.ReadConfigString(testnetconf);
BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_test_no_reg, error));
BOOST_CHECK(test_args.ParseParameters(2, argv_test_no_reg, error));
test_args.ReadConfigString(testnetconf);
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_both, error));
BOOST_CHECK(test_args.ParseParameters(3, argv_both, error));
test_args.ReadConfigString(testnetconf);
BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
}

View file

@ -112,7 +112,7 @@ bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vch
memcpy(chIV.data(), &nIV, WALLET_CRYPTO_IV_SIZE);
if(!cKeyCrypter.SetKey(vMasterKey, chIV))
return false;
return cKeyCrypter.Encrypt(*((const CKeyingMaterial*)&vchPlaintext), vchCiphertext);
return cKeyCrypter.Encrypt(vchPlaintext, vchCiphertext);
}
bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext)