xref: /aosp_15_r20/external/cronet/net/base/parse_number.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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