Skip to content

Commit f57e724

Browse files
committed
Merge bitcoin/bitcoin#28127: refactor: Remove C-style const-violating cast, Use reinterpret_cast
fa9108f refactor: Use reinterpret_cast where appropriate (MarcoFalke) 3333f95 refactor: Avoid casting away constness (MarcoFalke) fa6394d 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 https://github.com/bitcoin/bitcoin/blob/d23fda05842ba4539b225bbab01b94df0060f697/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 fa9108f hebasto: re-ACK fa9108f. john-moffett: ACK fa9108f Tree-SHA512: 87f6e4b574f9bd96d4e0f2a0631fd0a9dc6096e5d4f1b95042fe9f197afc2fe9a24e333aeb34fed11feefcdb184a238fe1ea5aff10d580bb18d76bfe48b76a10
2 parents f033a98 + fa9108f commit f57e724

File tree

5 files changed

+55
-53
lines changed

5 files changed

+55
-53
lines changed

src/crypto/common.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,73 +17,73 @@
1717
uint16_t static inline ReadLE16(const unsigned char* ptr)
1818
{
1919
uint16_t x;
20-
memcpy((char*)&x, ptr, 2);
20+
memcpy(&x, ptr, 2);
2121
return le16toh(x);
2222
}
2323

2424
uint32_t static inline ReadLE32(const unsigned char* ptr)
2525
{
2626
uint32_t x;
27-
memcpy((char*)&x, ptr, 4);
27+
memcpy(&x, ptr, 4);
2828
return le32toh(x);
2929
}
3030

3131
uint64_t static inline ReadLE64(const unsigned char* ptr)
3232
{
3333
uint64_t x;
34-
memcpy((char*)&x, ptr, 8);
34+
memcpy(&x, ptr, 8);
3535
return le64toh(x);
3636
}
3737

3838
void static inline WriteLE16(unsigned char* ptr, uint16_t x)
3939
{
4040
uint16_t v = htole16(x);
41-
memcpy(ptr, (char*)&v, 2);
41+
memcpy(ptr, &v, 2);
4242
}
4343

4444
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
4545
{
4646
uint32_t v = htole32(x);
47-
memcpy(ptr, (char*)&v, 4);
47+
memcpy(ptr, &v, 4);
4848
}
4949

5050
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
5151
{
5252
uint64_t v = htole64(x);
53-
memcpy(ptr, (char*)&v, 8);
53+
memcpy(ptr, &v, 8);
5454
}
5555

5656
uint16_t static inline ReadBE16(const unsigned char* ptr)
5757
{
5858
uint16_t x;
59-
memcpy((char*)&x, ptr, 2);
59+
memcpy(&x, ptr, 2);
6060
return be16toh(x);
6161
}
6262

6363
uint32_t static inline ReadBE32(const unsigned char* ptr)
6464
{
6565
uint32_t x;
66-
memcpy((char*)&x, ptr, 4);
66+
memcpy(&x, ptr, 4);
6767
return be32toh(x);
6868
}
6969

7070
uint64_t static inline ReadBE64(const unsigned char* ptr)
7171
{
7272
uint64_t x;
73-
memcpy((char*)&x, ptr, 8);
73+
memcpy(&x, ptr, 8);
7474
return be64toh(x);
7575
}
7676

7777
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
7878
{
7979
uint32_t v = htobe32(x);
80-
memcpy(ptr, (char*)&v, 4);
80+
memcpy(ptr, &v, 4);
8181
}
8282

8383
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
8484
{
8585
uint64_t v = htobe64(x);
86-
memcpy(ptr, (char*)&v, 8);
86+
memcpy(ptr, &v, 8);
8787
}
8888

8989
/** Return the smallest number n such that (x >> n) == 0 (or 64 if the highest bit in x is set. */

src/dbwrapper.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ struct DBParams {
5454
DBOptions options{};
5555
};
5656

57+
inline auto CharCast(const std::byte* data) { return reinterpret_cast<const char*>(data); }
58+
5759
class dbwrapper_error : public std::runtime_error
5860
{
5961
public:
@@ -113,12 +115,12 @@ class CDBBatch
113115
{
114116
ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
115117
ssKey << key;
116-
leveldb::Slice slKey((const char*)ssKey.data(), ssKey.size());
118+
leveldb::Slice slKey(CharCast(ssKey.data()), ssKey.size());
117119

118120
ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
119121
ssValue << value;
120122
ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent));
121-
leveldb::Slice slValue((const char*)ssValue.data(), ssValue.size());
123+
leveldb::Slice slValue(CharCast(ssValue.data()), ssValue.size());
122124

123125
batch.Put(slKey, slValue);
124126
// LevelDB serializes writes as:
@@ -138,7 +140,7 @@ class CDBBatch
138140
{
139141
ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
140142
ssKey << key;
141-
leveldb::Slice slKey((const char*)ssKey.data(), ssKey.size());
143+
leveldb::Slice slKey(CharCast(ssKey.data()), ssKey.size());
142144

143145
batch.Delete(slKey);
144146
// LevelDB serializes erases as:
@@ -177,7 +179,7 @@ class CDBIterator
177179
DataStream ssKey{};
178180
ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
179181
ssKey << key;
180-
leveldb::Slice slKey((const char*)ssKey.data(), ssKey.size());
182+
leveldb::Slice slKey(CharCast(ssKey.data()), ssKey.size());
181183
piter->Seek(slKey);
182184
}
183185

@@ -265,7 +267,7 @@ class CDBWrapper
265267
DataStream ssKey{};
266268
ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
267269
ssKey << key;
268-
leveldb::Slice slKey((const char*)ssKey.data(), ssKey.size());
270+
leveldb::Slice slKey(CharCast(ssKey.data()), ssKey.size());
269271

270272
std::string strValue;
271273
leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
@@ -307,7 +309,7 @@ class CDBWrapper
307309
DataStream ssKey{};
308310
ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
309311
ssKey << key;
310-
leveldb::Slice slKey((const char*)ssKey.data(), ssKey.size());
312+
leveldb::Slice slKey(CharCast(ssKey.data()), ssKey.size());
311313

312314
std::string strValue;
313315
leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
@@ -351,8 +353,8 @@ class CDBWrapper
351353
ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
352354
ssKey1 << key_begin;
353355
ssKey2 << key_end;
354-
leveldb::Slice slKey1((const char*)ssKey1.data(), ssKey1.size());
355-
leveldb::Slice slKey2((const char*)ssKey2.data(), ssKey2.size());
356+
leveldb::Slice slKey1(CharCast(ssKey1.data()), ssKey1.size());
357+
leveldb::Slice slKey2(CharCast(ssKey2.data()), ssKey2.size());
356358
uint64_t size = 0;
357359
leveldb::Range range(slKey1, slKey2);
358360
pdb->GetApproximateSizes(&range, 1, &size);

src/span.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
#ifndef BITCOIN_SPAN_H
66
#define BITCOIN_SPAN_H
77

8-
#include <type_traits>
9-
#include <cstddef>
108
#include <algorithm>
11-
#include <assert.h>
9+
#include <cassert>
10+
#include <cstddef>
11+
#include <type_traits>
1212

1313
#ifdef DEBUG
1414
#define CONSTEXPR_IF_NOT_DEBUG
@@ -267,10 +267,10 @@ Span<std::byte> MakeWritableByteSpan(V&& v) noexcept
267267
}
268268

269269
// Helper functions to safely cast to unsigned char pointers.
270-
inline unsigned char* UCharCast(char* c) { return (unsigned char*)c; }
270+
inline unsigned char* UCharCast(char* c) { return reinterpret_cast<unsigned char*>(c); }
271271
inline unsigned char* UCharCast(unsigned char* c) { return c; }
272-
inline unsigned char* UCharCast(std::byte* c) { return (unsigned char*)c; }
273-
inline const unsigned char* UCharCast(const char* c) { return (unsigned char*)c; }
272+
inline unsigned char* UCharCast(std::byte* c) { return reinterpret_cast<unsigned char*>(c); }
273+
inline const unsigned char* UCharCast(const char* c) { return reinterpret_cast<const unsigned char*>(c); }
274274
inline const unsigned char* UCharCast(const unsigned char* c) { return c; }
275275
inline const unsigned char* UCharCast(const std::byte* c) { return reinterpret_cast<const unsigned char*>(c); }
276276

src/test/argsman_tests.cpp

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class CheckValueTest : public TestChain100Setup
112112
test.SetupArgs({{"-value", flags}});
113113
const char* argv[] = {"ignored", arg};
114114
std::string error;
115-
bool success = test.ParseParameters(arg ? 2 : 1, (char**)argv, error);
115+
bool success = test.ParseParameters(arg ? 2 : 1, argv, error);
116116

117117
BOOST_CHECK_EQUAL(test.GetSetting("-value").write(), expect.setting.write());
118118
auto settings_list = test.GetSettingsList("-value");
@@ -217,13 +217,13 @@ BOOST_AUTO_TEST_CASE(util_ParseParameters)
217217
std::string error;
218218
LOCK(testArgs.cs_args);
219219
testArgs.SetupArgs({a, b, ccc, d});
220-
BOOST_CHECK(testArgs.ParseParameters(0, (char**)argv_test, error));
220+
BOOST_CHECK(testArgs.ParseParameters(0, argv_test, error));
221221
BOOST_CHECK(testArgs.m_settings.command_line_options.empty() && testArgs.m_settings.ro_config.empty());
222222

223-
BOOST_CHECK(testArgs.ParseParameters(1, (char**)argv_test, error));
223+
BOOST_CHECK(testArgs.ParseParameters(1, argv_test, error));
224224
BOOST_CHECK(testArgs.m_settings.command_line_options.empty() && testArgs.m_settings.ro_config.empty());
225225

226-
BOOST_CHECK(testArgs.ParseParameters(7, (char**)argv_test, error));
226+
BOOST_CHECK(testArgs.ParseParameters(7, argv_test, error));
227227
// expectation: -ignored is ignored (program name argument),
228228
// -a, -b and -ccc end up in map, -d ignored because it is after
229229
// a non-option argument (non-GNU option parsing)
@@ -248,17 +248,17 @@ BOOST_AUTO_TEST_CASE(util_ParseInvalidParameters)
248248

249249
const char* argv[] = {"ignored", "-registered"};
250250
std::string error;
251-
BOOST_CHECK(test.ParseParameters(2, (char**)argv, error));
251+
BOOST_CHECK(test.ParseParameters(2, argv, error));
252252
BOOST_CHECK_EQUAL(error, "");
253253

254254
argv[1] = "-unregistered";
255-
BOOST_CHECK(!test.ParseParameters(2, (char**)argv, error));
255+
BOOST_CHECK(!test.ParseParameters(2, argv, error));
256256
BOOST_CHECK_EQUAL(error, "Invalid parameter -unregistered");
257257

258258
// Make sure registered parameters prefixed with a chain type trigger errors.
259259
// (Previously, they were accepted and ignored.)
260260
argv[1] = "-test.registered";
261-
BOOST_CHECK(!test.ParseParameters(2, (char**)argv, error));
261+
BOOST_CHECK(!test.ParseParameters(2, argv, error));
262262
BOOST_CHECK_EQUAL(error, "Invalid parameter -test.registered");
263263
}
264264

@@ -269,7 +269,7 @@ static void TestParse(const std::string& str, bool expected_bool, int64_t expect
269269
std::string arg = "-value=" + str;
270270
const char* argv[] = {"ignored", arg.c_str()};
271271
std::string error;
272-
BOOST_CHECK(test.ParseParameters(2, (char**)argv, error));
272+
BOOST_CHECK(test.ParseParameters(2, argv, error));
273273
BOOST_CHECK_EQUAL(test.GetBoolArg("-value", false), expected_bool);
274274
BOOST_CHECK_EQUAL(test.GetBoolArg("-value", true), expected_bool);
275275
BOOST_CHECK_EQUAL(test.GetIntArg("-value", 99998), expected_int);
@@ -331,7 +331,7 @@ BOOST_AUTO_TEST_CASE(util_GetBoolArg)
331331
std::string error;
332332
LOCK(testArgs.cs_args);
333333
testArgs.SetupArgs({a, b, c, d, e, f});
334-
BOOST_CHECK(testArgs.ParseParameters(7, (char**)argv_test, error));
334+
BOOST_CHECK(testArgs.ParseParameters(7, argv_test, error));
335335

336336
// Each letter should be set.
337337
for (const char opt : "abcdef")
@@ -368,7 +368,7 @@ BOOST_AUTO_TEST_CASE(util_GetBoolArgEdgeCases)
368368
const char *argv_test[] = {"ignored", "-nofoo", "-foo", "-nobar=0"};
369369
testArgs.SetupArgs({foo, bar});
370370
std::string error;
371-
BOOST_CHECK(testArgs.ParseParameters(4, (char**)argv_test, error));
371+
BOOST_CHECK(testArgs.ParseParameters(4, argv_test, error));
372372

373373
// This was passed twice, second one overrides the negative setting.
374374
BOOST_CHECK(!testArgs.IsArgNegated("-foo"));
@@ -380,7 +380,7 @@ BOOST_AUTO_TEST_CASE(util_GetBoolArgEdgeCases)
380380

381381
// Config test
382382
const char *conf_test = "nofoo=1\nfoo=1\nnobar=0\n";
383-
BOOST_CHECK(testArgs.ParseParameters(1, (char**)argv_test, error));
383+
BOOST_CHECK(testArgs.ParseParameters(1, argv_test, error));
384384
testArgs.ReadConfigString(conf_test);
385385

386386
// This was passed twice, second one overrides the negative setting,
@@ -395,7 +395,7 @@ BOOST_AUTO_TEST_CASE(util_GetBoolArgEdgeCases)
395395
// Combined test
396396
const char *combo_test_args[] = {"ignored", "-nofoo", "-bar"};
397397
const char *combo_test_conf = "foo=1\nnobar=1\n";
398-
BOOST_CHECK(testArgs.ParseParameters(3, (char**)combo_test_args, error));
398+
BOOST_CHECK(testArgs.ParseParameters(3, combo_test_args, error));
399399
testArgs.ReadConfigString(combo_test_conf);
400400

401401
// Command line overrides, but doesn't erase old setting
@@ -655,62 +655,62 @@ BOOST_AUTO_TEST_CASE(util_GetChainTypeString)
655655
const char* testnetconf = "testnet=1\nregtest=0\n[test]\nregtest=1";
656656
std::string error;
657657

658-
BOOST_CHECK(test_args.ParseParameters(0, (char**)argv_testnet, error));
658+
BOOST_CHECK(test_args.ParseParameters(0, argv_testnet, error));
659659
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "main");
660660

661-
BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_testnet, error));
661+
BOOST_CHECK(test_args.ParseParameters(2, argv_testnet, error));
662662
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
663663

664-
BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_regtest, error));
664+
BOOST_CHECK(test_args.ParseParameters(2, argv_regtest, error));
665665
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "regtest");
666666

667-
BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_test_no_reg, error));
667+
BOOST_CHECK(test_args.ParseParameters(3, argv_test_no_reg, error));
668668
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
669669

670-
BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_both, error));
670+
BOOST_CHECK(test_args.ParseParameters(3, argv_both, error));
671671
BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
672672

673-
BOOST_CHECK(test_args.ParseParameters(0, (char**)argv_testnet, error));
673+
BOOST_CHECK(test_args.ParseParameters(0, argv_testnet, error));
674674
test_args.ReadConfigString(testnetconf);
675675
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
676676

677-
BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_testnet, error));
677+
BOOST_CHECK(test_args.ParseParameters(2, argv_testnet, error));
678678
test_args.ReadConfigString(testnetconf);
679679
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
680680

681-
BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_regtest, error));
681+
BOOST_CHECK(test_args.ParseParameters(2, argv_regtest, error));
682682
test_args.ReadConfigString(testnetconf);
683683
BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
684684

685-
BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_test_no_reg, error));
685+
BOOST_CHECK(test_args.ParseParameters(3, argv_test_no_reg, error));
686686
test_args.ReadConfigString(testnetconf);
687687
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
688688

689-
BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_both, error));
689+
BOOST_CHECK(test_args.ParseParameters(3, argv_both, error));
690690
test_args.ReadConfigString(testnetconf);
691691
BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
692692

693693
// check setting the network to test (and thus making
694694
// [test] regtest=1 potentially relevant) doesn't break things
695695
test_args.SelectConfigNetwork("test");
696696

697-
BOOST_CHECK(test_args.ParseParameters(0, (char**)argv_testnet, error));
697+
BOOST_CHECK(test_args.ParseParameters(0, argv_testnet, error));
698698
test_args.ReadConfigString(testnetconf);
699699
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
700700

701-
BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_testnet, error));
701+
BOOST_CHECK(test_args.ParseParameters(2, argv_testnet, error));
702702
test_args.ReadConfigString(testnetconf);
703703
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
704704

705-
BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_regtest, error));
705+
BOOST_CHECK(test_args.ParseParameters(2, argv_regtest, error));
706706
test_args.ReadConfigString(testnetconf);
707707
BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
708708

709-
BOOST_CHECK(test_args.ParseParameters(2, (char**)argv_test_no_reg, error));
709+
BOOST_CHECK(test_args.ParseParameters(2, argv_test_no_reg, error));
710710
test_args.ReadConfigString(testnetconf);
711711
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
712712

713-
BOOST_CHECK(test_args.ParseParameters(3, (char**)argv_both, error));
713+
BOOST_CHECK(test_args.ParseParameters(3, argv_both, error));
714714
test_args.ReadConfigString(testnetconf);
715715
BOOST_CHECK_THROW(test_args.GetChainTypeString(), std::runtime_error);
716716
}

src/wallet/crypter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vch
112112
memcpy(chIV.data(), &nIV, WALLET_CRYPTO_IV_SIZE);
113113
if(!cKeyCrypter.SetKey(vMasterKey, chIV))
114114
return false;
115-
return cKeyCrypter.Encrypt(*((const CKeyingMaterial*)&vchPlaintext), vchCiphertext);
115+
return cKeyCrypter.Encrypt(vchPlaintext, vchCiphertext);
116116
}
117117

118118
bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext)

0 commit comments

Comments
 (0)