Skip to content

Commit dada92f

Browse files
author
MarcoFalke
committed
Merge bitcoin/bitcoin#22875: util: Fix Racy ParseOpCode function initialization
7b481f0 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-ACK 7b481f0 🗣 Tree-SHA512: cbf9dc3af26d7335305026f32ce8472a018309b89b3d81a67357e59fbeed72c37b5b8a6e30325ea68145c3b2403867be82de01f22decefb6e6717cf0c0045633
2 parents 7551ae8 + 7b481f0 commit dada92f

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

src/core_read.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@
2121
#include <string>
2222

2323
namespace {
24-
25-
opcodetype ParseOpCode(const std::string& s)
24+
class OpCodeParser
2625
{
27-
static std::map<std::string, opcodetype> mapOpNames;
26+
private:
27+
std::map<std::string, opcodetype> mapOpNames;
2828

29-
if (mapOpNames.empty()) {
30-
for (unsigned int op = 0; op <= MAX_OPCODE; op++) {
29+
public:
30+
OpCodeParser()
31+
{
32+
for (unsigned int op = 0; op <= MAX_OPCODE; ++op) {
3133
// Allow OP_RESERVED to get into mapOpNames
3234
if (op < OP_NOP && op != OP_RESERVED) {
3335
continue;
@@ -44,10 +46,18 @@ opcodetype ParseOpCode(const std::string& s)
4446
}
4547
}
4648
}
49+
opcodetype Parse(const std::string& s) const
50+
{
51+
auto it = mapOpNames.find(s);
52+
if (it == mapOpNames.end()) throw std::runtime_error("script parse error: unknown opcode");
53+
return it->second;
54+
}
55+
};
4756

48-
auto it = mapOpNames.find(s);
49-
if (it == mapOpNames.end()) throw std::runtime_error("script parse error: unknown opcode");
50-
return it->second;
57+
opcodetype ParseOpCode(const std::string& s)
58+
{
59+
static const OpCodeParser ocp;
60+
return ocp.Parse(s);
5161
}
5262

5363
} // namespace

0 commit comments

Comments
 (0)