aboutsummaryrefslogtreecommitdiff
path: root/src/core_read.cpp
diff options
context:
space:
mode:
authorJeremy Rubin <j@rubin.io>2021-09-02 20:58:09 -0700
committerJeremy Rubin <j@rubin.io>2021-12-23 15:53:36 -0800
commit7b481f015a0386f5ee3e13415474952653ddc198 (patch)
treefa7bfcae56d38dca54eb05ee8d0ab3c66972d2f5 /src/core_read.cpp
parent4ad59042b359f473d5888ecee0c9288dcf98f1c9 (diff)
downloadbitcoin-7b481f015a0386f5ee3e13415474952653ddc198.tar.xz
Fix Racy ParseOpCode function initialization
Diffstat (limited to 'src/core_read.cpp')
-rw-r--r--src/core_read.cpp26
1 files changed, 18 insertions, 8 deletions
diff --git a/src/core_read.cpp b/src/core_read.cpp
index 484f41f262..1f9227bf0b 100644
--- a/src/core_read.cpp
+++ b/src/core_read.cpp
@@ -21,13 +21,15 @@
#include <string>
namespace {
-
-opcodetype ParseOpCode(const std::string& s)
+class OpCodeParser
{
- static std::map<std::string, opcodetype> mapOpNames;
+private:
+ std::map<std::string, opcodetype> mapOpNames;
- if (mapOpNames.empty()) {
- for (unsigned int op = 0; op <= MAX_OPCODE; op++) {
+public:
+ OpCodeParser()
+ {
+ for (unsigned int op = 0; op <= MAX_OPCODE; ++op) {
// Allow OP_RESERVED to get into mapOpNames
if (op < OP_NOP && op != OP_RESERVED) {
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);
- if (it == mapOpNames.end()) throw std::runtime_error("script parse error: unknown opcode");
- return it->second;
+opcodetype ParseOpCode(const std::string& s)
+{
+ static const OpCodeParser ocp;
+ return ocp.Parse(s);
}
} // namespace