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