1 // Copyright 2016 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_BASE_PARSE_NUMBER_H_ 6 #define NET_BASE_PARSE_NUMBER_H_ 7 8 #include <cstdint> 9 10 #include "base/strings/string_piece.h" 11 #include "net/base/net_export.h" 12 13 // This file contains utility functions for parsing numbers, in the context of 14 // network protocols. 15 // 16 // Q: Doesn't //base already provide these in string_number_conversions.h, with 17 // functions like base::StringToInt()? 18 // 19 // A: Yes, and those functions are used under the hood by these implementations. 20 // 21 // However using the base::StringTo*() has historically led to subtle bugs 22 // in the context of parsing network protocols: 23 // 24 // * Permitting a leading '+' 25 // * Incorrectly classifying overflow/underflow from a parsing failure 26 // * Allowing negative numbers for non-negative fields 27 // 28 // This API tries to avoid these problems by picking sensible defaults for 29 // //net code. For more details see crbug.com/596523. 30 31 namespace net { 32 33 // Format to use when parsing integers. 34 enum class ParseIntFormat { 35 // Accepts non-negative base 10 integers of the form: 36 // 37 // 1*DIGIT 38 // 39 // This construction is used in a variety of IETF standards, such as RFC 7230 40 // (HTTP). 41 // 42 // When attempting to parse a negative number using this format, the failure 43 // will be FAILED_PARSE since it violated the expected format (and not 44 // FAILED_UNDERFLOW). 45 // 46 // Also note that inputs need not be in minimal encoding: "0003" is valid and 47 // equivalent to "3". 48 NON_NEGATIVE, 49 50 // Accept optionally negative base 10 integers of the form: 51 // 52 // ["-"] 1*DIGIT 53 // 54 // In other words, this accepts the same things as NON_NEGATIVE, and 55 // additionally recognizes those numbers prefixed with a '-'. 56 // 57 // Note that by this definition "-0" IS a valid input. 58 OPTIONALLY_NEGATIVE, 59 60 // Like NON_NEGATIVE, but rejects anything not in minimal encoding - that is, 61 // it rejects anything with leading 0's, except "0". 62 STRICT_NON_NEGATIVE, 63 64 // Like OPTIONALLY_NEGATIVE, but rejects anything not in minimal encoding - 65 // that is, it rejects "-0" and anything with leading 0's, except "0". 66 STRICT_OPTIONALLY_NEGATIVE, 67 }; 68 69 // The specific reason why a ParseInt*() function failed. 70 enum class ParseIntError { 71 // The parsed number couldn't fit into the provided output type because it was 72 // too high. 73 FAILED_OVERFLOW, 74 75 // The parsed number couldn't fit into the provided output type because it was 76 // too low. 77 FAILED_UNDERFLOW, 78 79 // The number failed to be parsed because it wasn't a valid decimal number (as 80 // determined by the policy). 81 FAILED_PARSE, 82 }; 83 84 // The ParseInt*() functions parse a string representing a number. 85 // 86 // The format of the strings that are accepted is controlled by the |format| 87 // parameter. This allows rejecting negative numbers. 88 // 89 // These functions return true on success, and fill |*output| with the result. 90 // 91 // On failure, it is guaranteed that |*output| was not modified. If 92 // |optional_error| was non-null, then it is filled with the reason for the 93 // failure. 94 [[nodiscard]] NET_EXPORT bool ParseInt32( 95 base::StringPiece input, 96 ParseIntFormat format, 97 int32_t* output, 98 ParseIntError* optional_error = nullptr); 99 100 [[nodiscard]] NET_EXPORT bool ParseInt64( 101 base::StringPiece input, 102 ParseIntFormat format, 103 int64_t* output, 104 ParseIntError* optional_error = nullptr); 105 106 // The ParseUint*() functions parse a string representing a number. 107 // 108 // These are equivalent to calling ParseInt*(), except with unsigned output 109 // types. ParseIntFormat may only be one of {NON_NEGATIVE, STRICT_NON_NEGATIVE}. 110 [[nodiscard]] NET_EXPORT bool ParseUint32( 111 base::StringPiece input, 112 ParseIntFormat format, 113 uint32_t* output, 114 ParseIntError* optional_error = nullptr); 115 116 [[nodiscard]] NET_EXPORT bool ParseUint64( 117 base::StringPiece input, 118 ParseIntFormat format, 119 uint64_t* output, 120 ParseIntError* optional_error = nullptr); 121 122 } // namespace net 123 124 #endif // NET_BASE_PARSE_NUMBER_H_ 125