Skip to content

Commit 4d73691

Browse files
committed
Disallow automatic conversion between hash types
A templated BaseHash does not allow for automatic conversion, thus conversions much be explicitly allowed / whitelisted, which will reduce the risk of unintended conversions.
1 parent fa9ef2c commit 4d73691

File tree

2 files changed

+85
-23
lines changed

2 files changed

+85
-23
lines changed

src/script/standard.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,17 @@ typedef std::vector<unsigned char> valtype;
1616
bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER;
1717
unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;
1818

19-
CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {}
20-
CScriptID::CScriptID(const ScriptHash& in) : uint160(static_cast<uint160>(in)) {}
19+
CScriptID::CScriptID(const CScript& in) : BaseHash(Hash160(in.begin(), in.end())) {}
20+
CScriptID::CScriptID(const ScriptHash& in) : BaseHash(static_cast<uint160>(in)) {}
2121

22-
ScriptHash::ScriptHash(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {}
23-
ScriptHash::ScriptHash(const CScriptID& in) : uint160(static_cast<uint160>(in)) {}
22+
ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in.begin(), in.end())) {}
23+
ScriptHash::ScriptHash(const CScriptID& in) : BaseHash(static_cast<uint160>(in)) {}
2424

25-
PKHash::PKHash(const CPubKey& pubkey) : uint160(pubkey.GetID()) {}
26-
PKHash::PKHash(const CKeyID& pubkey_id) : uint160(pubkey_id) {}
25+
PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
26+
PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {}
2727

28-
WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : uint160(pubkey.GetID()) {}
29-
WitnessV0KeyHash::WitnessV0KeyHash(const PKHash& pubkey_hash) : uint160(static_cast<uint160>(pubkey_hash)) {}
28+
WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
29+
WitnessV0KeyHash::WitnessV0KeyHash(const PKHash& pubkey_hash) : BaseHash(static_cast<uint160>(pubkey_hash)) {}
3030

3131
CKeyID ToKeyID(const PKHash& key_hash)
3232
{

src/script/standard.h

Lines changed: 77 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,74 @@ class CKeyID;
2020
class CScript;
2121
struct ScriptHash;
2222

23+
template<typename HashType>
24+
class BaseHash
25+
{
26+
protected:
27+
HashType m_hash;
28+
29+
public:
30+
BaseHash() : m_hash() {}
31+
BaseHash(const HashType& in) : m_hash(in) {}
32+
33+
unsigned char* begin()
34+
{
35+
return m_hash.begin();
36+
}
37+
38+
const unsigned char* begin() const
39+
{
40+
return m_hash.begin();
41+
}
42+
43+
unsigned char* end()
44+
{
45+
return m_hash.end();
46+
}
47+
48+
const unsigned char* end() const
49+
{
50+
return m_hash.end();
51+
}
52+
53+
operator std::vector<unsigned char>() const
54+
{
55+
return std::vector<unsigned char>{m_hash.begin(), m_hash.end()};
56+
}
57+
58+
std::string ToString() const
59+
{
60+
return m_hash.ToString();
61+
}
62+
63+
bool operator==(const BaseHash<HashType>& other) const noexcept
64+
{
65+
return m_hash == other.m_hash;
66+
}
67+
68+
bool operator!=(const BaseHash<HashType>& other) const noexcept
69+
{
70+
return !(m_hash == other.m_hash);
71+
}
72+
73+
bool operator<(const BaseHash<HashType>& other) const noexcept
74+
{
75+
return m_hash < other.m_hash;
76+
}
77+
78+
size_t size() const
79+
{
80+
return m_hash.size();
81+
}
82+
};
83+
2384
/** A reference to a CScript: the Hash160 of its serialization (see script.h) */
24-
class CScriptID : public uint160
85+
class CScriptID : public BaseHash<uint160>
2586
{
2687
public:
27-
CScriptID() : uint160() {}
88+
CScriptID() : BaseHash() {}
2889
explicit CScriptID(const CScript& in);
29-
explicit CScriptID(const uint160& in) : uint160(in) {}
90+
explicit CScriptID(const uint160& in) : BaseHash(in) {}
3091
explicit CScriptID(const ScriptHash& in);
3192
};
3293

@@ -75,39 +136,40 @@ class CNoDestination {
75136
friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; }
76137
};
77138

78-
struct PKHash : public uint160
139+
struct PKHash : public BaseHash<uint160>
79140
{
80-
PKHash() : uint160() {}
81-
explicit PKHash(const uint160& hash) : uint160(hash) {}
141+
PKHash() : BaseHash() {}
142+
explicit PKHash(const uint160& hash) : BaseHash(hash) {}
82143
explicit PKHash(const CPubKey& pubkey);
83144
explicit PKHash(const CKeyID& pubkey_id);
84145
};
85146
CKeyID ToKeyID(const PKHash& key_hash);
86147

87148
struct WitnessV0KeyHash;
88-
struct ScriptHash : public uint160
149+
struct ScriptHash : public BaseHash<uint160>
89150
{
90-
ScriptHash() : uint160() {}
151+
ScriptHash() : BaseHash() {}
91152
// These don't do what you'd expect.
92153
// Use ScriptHash(GetScriptForDestination(...)) instead.
93154
explicit ScriptHash(const WitnessV0KeyHash& hash) = delete;
94155
explicit ScriptHash(const PKHash& hash) = delete;
95-
explicit ScriptHash(const uint160& hash) : uint160(hash) {}
156+
157+
explicit ScriptHash(const uint160& hash) : BaseHash(hash) {}
96158
explicit ScriptHash(const CScript& script);
97159
explicit ScriptHash(const CScriptID& script);
98160
};
99161

100-
struct WitnessV0ScriptHash : public uint256
162+
struct WitnessV0ScriptHash : public BaseHash<uint256>
101163
{
102-
WitnessV0ScriptHash() : uint256() {}
103-
explicit WitnessV0ScriptHash(const uint256& hash) : uint256(hash) {}
164+
WitnessV0ScriptHash() : BaseHash() {}
165+
explicit WitnessV0ScriptHash(const uint256& hash) : BaseHash(hash) {}
104166
explicit WitnessV0ScriptHash(const CScript& script);
105167
};
106168

107-
struct WitnessV0KeyHash : public uint160
169+
struct WitnessV0KeyHash : public BaseHash<uint160>
108170
{
109-
WitnessV0KeyHash() : uint160() {}
110-
explicit WitnessV0KeyHash(const uint160& hash) : uint160(hash) {}
171+
WitnessV0KeyHash() : BaseHash() {}
172+
explicit WitnessV0KeyHash(const uint160& hash) : BaseHash(hash) {}
111173
explicit WitnessV0KeyHash(const CPubKey& pubkey);
112174
explicit WitnessV0KeyHash(const PKHash& pubkey_hash);
113175
};

0 commit comments

Comments
 (0)