aboutsummaryrefslogtreecommitdiff
path: root/disasm
diff options
context:
space:
mode:
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;
}