aboutsummaryrefslogtreecommitdiff
path: root/disasm
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2024-09-20 04:06:38 -0700
committerAndrew Waterman <andrew@sifive.com>2024-09-20 04:39:18 -0700
commit9a641bb03e6b5318a09eff4cd08b2aa00ec92e97 (patch)
tree7ff42d8d2a46502735fd5f59234584da3e6f50f3 /disasm
parent19fdd76e056dcfd041901ce9b8e0031944de7209 (diff)
downloadriscv-isa-sim-9a641bb03e6b5318a09eff4cd08b2aa00ec92e97.zip
riscv-isa-sim-9a641bb03e6b5318a09eff4cd08b2aa00ec92e97.tar.gz
riscv-isa-sim-9a641bb03e6b5318a09eff4cd08b2aa00ec92e97.tar.bz2
Validate Zvl ISA string correctly
See #1810 for explanation of how this can go wrong. Resolves #1810
Diffstat (limited to 'disasm')
-rw-r--r--disasm/isa_parser.cc24
1 files changed, 22 insertions, 2 deletions
diff --git a/disasm/isa_parser.cc b/disasm/isa_parser.cc
index 1c0a0c4..b5c8b80 100644
--- a/disasm/isa_parser.cc
+++ b/disasm/isa_parser.cc
@@ -9,6 +9,26 @@ static std::string strtolower(const char* str)
return res;
}
+static unsigned long safe_stoul(const std::string& s)
+{
+ int old_errno = errno;
+ errno = 0;
+
+ char* endp;
+ unsigned long ret = strtoul(s.c_str(), &endp, 10);
+
+ int new_errno = errno;
+ errno = old_errno;
+
+ if (endp == s.c_str() || *endp)
+ throw std::invalid_argument("stoul");
+
+ if (new_errno)
+ throw std::out_of_range("stoul");
+
+ return ret;
+}
+
static void bad_option_string(const char *option, const char *value,
const char *msg)
{
@@ -327,7 +347,7 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
} else if (ext_str.substr(0, 3) == "zvl") {
reg_t new_vlen;
try {
- new_vlen = std::stol(ext_str.substr(3, ext_str.size() - 4));
+ new_vlen = safe_stoul(ext_str.substr(3, ext_str.size() - 4));
} catch (std::logic_error& e) {
new_vlen = 0;
}
@@ -337,7 +357,7 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
} else if (ext_str.substr(0, 3) == "zve") {
reg_t new_elen;
try {
- new_elen = std::stol(ext_str.substr(3, ext_str.size() - 4));
+ new_elen = safe_stoul(ext_str.substr(3, ext_str.size() - 4));
} catch (std::logic_error& e) {
new_elen = 0;
}