From: Kefu Chai Date: Thu, 19 Apr 2018 11:19:30 +0000 (+0800) Subject: common/strtol: fix strict_strtoll() so it accepts hex starting with 0x X-Git-Tag: v13.1.0~164^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F21521%2Fhead;p=ceph.git common/strtol: fix strict_strtoll() so it accepts hex starting with 0x - simplify the error handling of strtoll(). - only instantiate ostringstream when handling errors. Signed-off-by: Kefu Chai --- diff --git a/src/common/strtol.cc b/src/common/strtol.cc index b2a90963dff13..7f7e78bfbd0db 100644 --- a/src/common/strtol.cc +++ b/src/common/strtol.cc @@ -24,27 +24,17 @@ using std::ostringstream; long long strict_strtoll(const std::string_view str, int base, std::string *err) { - ostringstream errStr; - if (auto invalid = str.find_first_not_of("0123456789-+"); - invalid != std::string_view::npos || - invalid == 0) { - errStr << "The option value '" << str << "' contains invalid digits"; - *err = errStr.str(); - return 0; - } char *endptr; errno = 0; /* To distinguish success/failure after call (see man page) */ long long ret = strtoll(str.data(), &endptr, base); - - if (endptr == str.data()) { - errStr << "Expected option value to be integer, got '" << str << "'"; - *err = errStr.str(); + if (endptr == str.data() || endptr != str.data() + str.size()) { + *err = (std::string{"Expected option value to be integer, got '"} + + std::string{str} + "'"); return 0; } - if ((errno == ERANGE && (ret == LLONG_MAX || ret == LLONG_MIN)) - || (errno != 0 && ret == 0)) { - errStr << "The option value '" << str << "' seems to be invalid"; - *err = errStr.str(); + if (errno) { + *err = (std::string{"The option value '"} + std::string{str} + + "' seems to be invalid"); return 0; } *err = ""; @@ -58,11 +48,11 @@ long long strict_strtoll(const char *str, int base, std::string *err) int strict_strtol(const std::string_view str, int base, std::string *err) { - ostringstream errStr; long long ret = strict_strtoll(str, base, err); if (!err->empty()) return 0; if ((ret < INT_MIN) || (ret > INT_MAX)) { + ostringstream errStr; errStr << "The option value '" << str << "' seems to be invalid"; *err = errStr.str(); return 0; @@ -78,21 +68,23 @@ int strict_strtol(const char *str, int base, std::string *err) double strict_strtod(const std::string_view str, std::string *err) { char *endptr; - ostringstream oss; errno = 0; /* To distinguish success/failure after call (see man page) */ double ret = strtod(str.data(), &endptr); if (errno == ERANGE) { + ostringstream oss; oss << "strict_strtod: floating point overflow or underflow parsing '" << str << "'"; *err = oss.str(); return 0.0; } if (endptr == str) { + ostringstream oss; oss << "strict_strtod: expected double, got: '" << str << "'"; *err = oss.str(); return 0; } if (*endptr != '\0') { + ostringstream oss; oss << "strict_strtod: garbage at end of string. got: '" << str << "'"; *err = oss.str(); return 0; @@ -109,21 +101,23 @@ double strict_strtod(const char *str, std::string *err) float strict_strtof(const std::string_view str, std::string *err) { char *endptr; - ostringstream oss; errno = 0; /* To distinguish success/failure after call (see man page) */ float ret = strtof(str.data(), &endptr); if (errno == ERANGE) { + ostringstream oss; oss << "strict_strtof: floating point overflow or underflow parsing '" << str << "'"; *err = oss.str(); return 0.0; } if (endptr == str) { + ostringstream oss; oss << "strict_strtof: expected float, got: '" << str << "'"; *err = oss.str(); return 0; } if (*endptr != '\0') { + ostringstream oss; oss << "strict_strtof: garbage at end of string. got: '" << str << "'"; *err = oss.str(); return 0; diff --git a/src/test/cli/monmaptool/feature-set-unset-list.t b/src/test/cli/monmaptool/feature-set-unset-list.t index f574b4318f990..216566ebb48a0 100644 --- a/src/test/cli/monmaptool/feature-set-unset-list.t +++ b/src/test/cli/monmaptool/feature-set-unset-list.t @@ -28,7 +28,7 @@ available:persistent:[kraken(1),luminous(2),mimic(4),osdmap-prune(8)] $ monmaptool --feature-set foo /tmp/test.monmap.1234 - unknown features name 'foo' or unable to parse value: The option value 'foo' contains invalid digits + unknown features name 'foo' or unable to parse value: Expected option value to be integer, got 'foo' usage: [--print] [--create [--clobber][--fsid uuid]] [--generate] [--set-initial-members] [--add name 1.2.3.4:567] [--rm name]