Page MenuHomePhabricator

D11078.diff
No OneTemporary

D11078.diff

diff --git a/src/test/fuzz/parse_numbers.cpp b/src/test/fuzz/parse_numbers.cpp
--- a/src/test/fuzz/parse_numbers.cpp
+++ b/src/test/fuzz/parse_numbers.cpp
@@ -21,6 +21,9 @@
uint8_t u8;
(void)ParseUInt8(random_string, &u8);
+ uint16_t u16;
+ (void)ParseUInt16(random_string, &u16);
+
int32_t i32;
(void)ParseInt32(random_string, &i32);
(void)atoi(random_string);
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -1740,6 +1740,40 @@
BOOST_CHECK(!ParseUInt8("256", nullptr));
}
+BOOST_AUTO_TEST_CASE(test_ParseUInt16) {
+ uint16_t n;
+ // Valid values
+ BOOST_CHECK(ParseUInt16("1234", nullptr));
+ BOOST_CHECK(ParseUInt16("0", &n) && n == 0);
+ BOOST_CHECK(ParseUInt16("1234", &n) && n == 1234);
+ BOOST_CHECK(ParseUInt16("01234", &n) && n == 1234); // no octal
+ BOOST_CHECK(ParseUInt16("65535", &n) && n == static_cast<uint16_t>(65535));
+ BOOST_CHECK(ParseUInt16("+65535", &n) && n == 65535);
+ BOOST_CHECK(ParseUInt16("00000000000000000012", &n) && n == 12);
+ BOOST_CHECK(ParseUInt16("00000000000000000000", &n) && n == 0);
+ // Invalid values
+ BOOST_CHECK(!ParseUInt16("-00000000000000000000", &n));
+ BOOST_CHECK(!ParseUInt16("", &n));
+ BOOST_CHECK(!ParseUInt16(" 1", &n)); // no padding inside
+ BOOST_CHECK(!ParseUInt16(" -1", &n));
+ BOOST_CHECK(!ParseUInt16("++1", &n));
+ BOOST_CHECK(!ParseUInt16("+-1", &n));
+ BOOST_CHECK(!ParseUInt16("-+1", &n));
+ BOOST_CHECK(!ParseUInt16("--1", &n));
+ BOOST_CHECK(!ParseUInt16("-1", &n));
+ BOOST_CHECK(!ParseUInt16("1 ", &n));
+ BOOST_CHECK(!ParseUInt16("1a", &n));
+ BOOST_CHECK(!ParseUInt16("aap", &n));
+ BOOST_CHECK(!ParseUInt16("0x1", &n)); // no hex
+ BOOST_CHECK(!ParseUInt16(STRING_WITH_EMBEDDED_NULL_CHAR, &n));
+ // Overflow and underflow
+ BOOST_CHECK(!ParseUInt16("-65535", &n));
+ BOOST_CHECK(!ParseUInt16("65536", &n));
+ BOOST_CHECK(!ParseUInt16("-123", &n));
+ BOOST_CHECK(!ParseUInt16("-123", nullptr));
+ BOOST_CHECK(!ParseUInt16("65536", nullptr));
+}
+
BOOST_AUTO_TEST_CASE(test_ParseUInt32) {
uint32_t n;
// Valid values
diff --git a/src/util/strencodings.h b/src/util/strencodings.h
--- a/src/util/strencodings.h
+++ b/src/util/strencodings.h
@@ -127,6 +127,15 @@
*/
[[nodiscard]] bool ParseUInt8(const std::string &str, uint8_t *out);
+/**
+ * Convert decimal string to unsigned 16-bit integer with strict parse error
+ * feedback.
+ * @returns true if the entire string could be parsed as valid integer,
+ * false if the entire string could not be parsed or if overflow or underflow
+ * occurred.
+ */
+[[nodiscard]] bool ParseUInt16(const std::string &str, uint16_t *out);
+
/**
* Convert decimal string to unsigned 32-bit integer with strict parse error
* feedback.
diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp
--- a/src/util/strencodings.cpp
+++ b/src/util/strencodings.cpp
@@ -121,8 +121,8 @@
bool fMultiColon =
fHaveColon && (in.find_last_of(':', colon - 1) != in.npos);
if (fHaveColon && (colon == 0 || fBracketed || !fMultiColon)) {
- int32_t n;
- if (ParseInt32(in.substr(colon + 1), &n) && n > 0 && n < 0x10000) {
+ uint16_t n;
+ if (ParseUInt16(in.substr(colon + 1), &n)) {
in = in.substr(0, colon);
portOut = n;
}
@@ -361,6 +361,17 @@
return true;
}
+bool ParseUInt16(const std::string &str, uint16_t *out) {
+ uint32_t u32;
+ if (!ParseUInt32(str, &u32) || u32 > std::numeric_limits<uint16_t>::max()) {
+ return false;
+ }
+ if (out != nullptr) {
+ *out = static_cast<uint16_t>(u32);
+ }
+ return true;
+}
+
bool ParseUInt32(const std::string &str, uint32_t *out) {
if (!ParsePrechecks(str)) {
return false;

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 1, 11:49 (6 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5187698
Default Alt Text
D11078.diff (3 KB)

Event Timeline