Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Unified Diff: net/base/parse_number.cc

Issue 1828103002: Extend net/base/parse_number.h for parsing of negative numbers, and determining if there was overflo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@proxy_num
Patch Set: fix comments Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/base/parse_number.h ('k') | net/base/parse_number_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/base/parse_number.cc
diff --git a/net/base/parse_number.cc b/net/base/parse_number.cc
index d315bec63a906dba00b5f27e56dd20161ace6266..365aa350b472c1f58e29903d91943f4fcc69c096 100644
--- a/net/base/parse_number.cc
+++ b/net/base/parse_number.cc
@@ -4,20 +4,123 @@
#include "net/base/parse_number.h"
+#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
namespace net {
-bool ParseNonNegativeDecimalInt(const base::StringPiece& input, int* output) {
- if (input.empty() || input[0] > '9' || input[0] < '0')
- return false;
+namespace {
+
+// The string to number conversion functions in //base include the type in the
+// name (like StringToInt64()). The following wrapper methods create a
+// consistent interface to StringToXXX() that calls the appropriate //base
+// version. This simplifies writing generic code with a template.
+
+bool StringToNumber(const base::StringPiece& input, int32_t* output) {
+ // This assumes ints are 32-bits (will fail compile if that ever changes).
+ return base::StringToInt(input, output);
+}
+
+bool StringToNumber(const base::StringPiece& input, uint32_t* output) {
+ // This assumes ints are 32-bits (will fail compile if that ever changes).
+ return base::StringToUint(input, output);
+}
+
+bool StringToNumber(const base::StringPiece& input, int64_t* output) {
+ return base::StringToInt64(input, output);
+}
+
+bool StringToNumber(const base::StringPiece& input, uint64_t* output) {
+ return base::StringToUint64(input, output);
+}
+
+bool SetError(ParseIntError error, ParseIntError* optional_error) {
+ if (optional_error)
+ *optional_error = error;
+ return false;
+}
+
+template <typename T>
+bool ParseIntHelper(const base::StringPiece& input,
+ ParseIntFormat format,
+ T* output,
+ ParseIntError* optional_error) {
+ // Check that the input matches the format before calling StringToNumber().
+ // Numbers must start with either a digit or a negative sign.
+ if (input.empty())
+ return SetError(ParseIntError::FAILED_PARSE, optional_error);
+
+ bool starts_with_negative = input[0] == '-';
+ bool starts_with_digit = input[0] >= '0' && input[0] <= '9';
- int result;
- if (!base::StringToInt(input, &result))
+ if (!starts_with_digit) {
+ if (format == ParseIntFormat::NON_NEGATIVE || !starts_with_negative)
+ return SetError(ParseIntError::FAILED_PARSE, optional_error);
+ }
+
+ // Dispatch to the appropriate flavor of base::StringToXXX() by calling one of
+ // the type-specific overloads.
+ T result;
+ if (StringToNumber(input, &result)) {
+ *output = result;
+ return true;
+ }
+
+ // Optimization: If the error is not going to be inspected, don't bother
+ // calculating it.
+ if (!optional_error)
return false;
- *output = result;
- return true;
+ // Set an error that distinguishes between parsing/underflow/overflow errors.
+ //
+ // Note that the output set by base::StringToXXX() on failure cannot be used
+ // as it has ambiguity with parse errors.
+
+ // Strip any leading negative sign off the number.
+ base::StringPiece numeric_portion =
+ starts_with_negative ? input.substr(1) : input;
+
+ // Test if |numeric_portion| is a valid non-negative integer.
+ if (!numeric_portion.empty() &&
+ numeric_portion.find_first_not_of("0123456789") == std::string::npos) {
+ // If it was, the failure must have been due to underflow/overflow.
+ return SetError(starts_with_negative ? ParseIntError::FAILED_UNDERFLOW
+ : ParseIntError::FAILED_OVERFLOW,
+ optional_error);
+ }
+
+ // Otherwise it was a mundane parsing error.
+ return SetError(ParseIntError::FAILED_PARSE, optional_error);
+}
+
+} // namespace
+
+bool ParseInt32(const base::StringPiece& input,
+ ParseIntFormat format,
+ int32_t* output,
+ ParseIntError* optional_error) {
+ return ParseIntHelper(input, format, output, optional_error);
+}
+
+bool ParseInt64(const base::StringPiece& input,
+ ParseIntFormat format,
+ int64_t* output,
+ ParseIntError* optional_error) {
+ return ParseIntHelper(input, format, output, optional_error);
+}
+
+bool ParseUint32(const base::StringPiece& input,
+ uint32_t* output,
+ ParseIntError* optional_error) {
+ return ParseIntHelper(input, ParseIntFormat::NON_NEGATIVE, output,
+ optional_error);
+}
+
+bool ParseUint64(const base::StringPiece& input,
+ uint64_t* output,
+ ParseIntError* optional_error) {
+ return ParseIntHelper(input, ParseIntFormat::NON_NEGATIVE, output,
+ optional_error);
}
} // namespace net
« no previous file with comments | « net/base/parse_number.h ('k') | net/base/parse_number_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698