• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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