mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-05 14:06:27 -05:00
Merge bitcoin/bitcoin#22875: util: Fix Racy ParseOpCode function initialization
7b481f015a
Fix Racy ParseOpCode function initialization (Jeremy Rubin) Pull request description: If multiple callers call ParseOpCode concurrently it will cause a race condition. We can either move the static to it's own area and require init be called explicitly, or just allow concurrent first callers to race to fill in an atomic variable that never changes thereafter. The second approach is taken here. Static initialization *is* threadsafe, but only insofar as definining the variable being guaranteed to be called once. This is used incorrectly here. practicalswift --> are there tools we can deploy to catch usage like this? ACKs for top commit: MarcoFalke: re-ACK7b481f015a
🗣 Tree-SHA512: cbf9dc3af26d7335305026f32ce8472a018309b89b3d81a67357e59fbeed72c37b5b8a6e30325ea68145c3b2403867be82de01f22decefb6e6717cf0c0045633
This commit is contained in:
commit
dada92fed2
1 changed files with 18 additions and 8 deletions
|
@ -21,13 +21,15 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
class OpCodeParser
|
||||||
opcodetype ParseOpCode(const std::string& s)
|
|
||||||
{
|
{
|
||||||
static std::map<std::string, opcodetype> mapOpNames;
|
private:
|
||||||
|
std::map<std::string, opcodetype> mapOpNames;
|
||||||
|
|
||||||
if (mapOpNames.empty()) {
|
public:
|
||||||
for (unsigned int op = 0; op <= MAX_OPCODE; op++) {
|
OpCodeParser()
|
||||||
|
{
|
||||||
|
for (unsigned int op = 0; op <= MAX_OPCODE; ++op) {
|
||||||
// Allow OP_RESERVED to get into mapOpNames
|
// Allow OP_RESERVED to get into mapOpNames
|
||||||
if (op < OP_NOP && op != OP_RESERVED) {
|
if (op < OP_NOP && op != OP_RESERVED) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -44,10 +46,18 @@ opcodetype ParseOpCode(const std::string& s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
opcodetype Parse(const std::string& s) const
|
||||||
|
{
|
||||||
|
auto it = mapOpNames.find(s);
|
||||||
|
if (it == mapOpNames.end()) throw std::runtime_error("script parse error: unknown opcode");
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
auto it = mapOpNames.find(s);
|
opcodetype ParseOpCode(const std::string& s)
|
||||||
if (it == mapOpNames.end()) throw std::runtime_error("script parse error: unknown opcode");
|
{
|
||||||
return it->second;
|
static const OpCodeParser ocp;
|
||||||
|
return ocp.Parse(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
Loading…
Add table
Reference in a new issue