aboutsummaryrefslogtreecommitdiff
path: root/src/utilstrencodings.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2016-06-08 10:23:25 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2016-06-08 10:28:51 +0200
commite012f3cea0ca4096dd4dd59a356a973c43651912 (patch)
tree2d6b478372ca006337efe387ad9f6818caec56d3 /src/utilstrencodings.cpp
parent0f24eaf253abe7d1479777ef10f8f4e8eeb9d06e (diff)
util: Add ParseUInt32 and ParseUInt64
Add error and range-checking parsers for unsigned 32 and 64 bit numbers. The 32-bit variant is required for parsing sequence numbers from the command line in `bitcoin-tx` (see #8164 for discussion). I've thrown in the 64-bit variant as a bonus, as I'm sure it will be needed at some point. Also adds tests, and updates `developer-notes.md`.
Diffstat (limited to 'src/utilstrencodings.cpp')
-rw-r--r--src/utilstrencodings.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp
index 0f9334cbe3..5ffdb3be15 100644
--- a/src/utilstrencodings.cpp
+++ b/src/utilstrencodings.cpp
@@ -461,6 +461,40 @@ bool ParseInt64(const std::string& str, int64_t *out)
n <= std::numeric_limits<int64_t>::max();
}
+bool ParseUInt32(const std::string& str, uint32_t *out)
+{
+ if (!ParsePrechecks(str))
+ return false;
+ if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoul accepts these by default if they fit in the range
+ return false;
+ char *endp = NULL;
+ errno = 0; // strtoul will not set errno if valid
+ unsigned long int n = strtoul(str.c_str(), &endp, 10);
+ if(out) *out = (uint32_t)n;
+ // Note that strtoul returns a *unsigned long int*, so even if it doesn't report a over/underflow
+ // we still have to check that the returned value is within the range of an *uint32_t*. On 64-bit
+ // platforms the size of these types may be different.
+ return endp && *endp == 0 && !errno &&
+ n <= std::numeric_limits<uint32_t>::max();
+}
+
+bool ParseUInt64(const std::string& str, uint64_t *out)
+{
+ if (!ParsePrechecks(str))
+ return false;
+ if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoull accepts these by default if they fit in the range
+ return false;
+ char *endp = NULL;
+ errno = 0; // strtoull will not set errno if valid
+ unsigned long long int n = strtoull(str.c_str(), &endp, 10);
+ if(out) *out = (uint64_t)n;
+ // Note that strtoull returns a *unsigned long long int*, so even if it doesn't report a over/underflow
+ // we still have to check that the returned value is within the range of an *uint64_t*.
+ return endp && *endp == 0 && !errno &&
+ n <= std::numeric_limits<uint64_t>::max();
+}
+
+
bool ParseDouble(const std::string& str, double *out)
{
if (!ParsePrechecks(str))