parse_number_unittest.cc 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/base/parse_number.h"
  5. #include <limits>
  6. #include <sstream>
  7. #include "base/strings/string_number_conversions.h"
  8. #include "testing/gtest/include/gtest/gtest.h"
  9. namespace net {
  10. namespace {
  11. // Returns a decimal string that is one larger than the maximum value that type
  12. // T can represent.
  13. template <typename T>
  14. std::string CreateOverflowString() {
  15. const T value = std::numeric_limits<T>::max();
  16. std::string result = base::NumberToString(value);
  17. EXPECT_NE('9', result.back());
  18. result.back()++;
  19. return result;
  20. }
  21. // Returns a decimal string that is one less than the minimum value that
  22. // (signed) type T can represent.
  23. template <typename T>
  24. std::string CreateUnderflowString() {
  25. EXPECT_TRUE(std::numeric_limits<T>::is_signed);
  26. const T value = std::numeric_limits<T>::min();
  27. std::string result = base::NumberToString(value);
  28. EXPECT_EQ('-', result.front());
  29. EXPECT_NE('9', result.back());
  30. result.back()++;
  31. return result;
  32. }
  33. // These are valid inputs representing non-negative integers. Note that these
  34. // test inputs are re-used when constructing negative test cases, by simply
  35. // prepending a '-'.
  36. const struct {
  37. const char* input;
  38. int expected_output;
  39. } kValidNonNegativeTests[] = {
  40. {"0", 0}, {"00000", 0}, {"003", 3}, {"003", 3}, {"1234566", 1234566},
  41. {"987", 987}, {"010", 10},
  42. };
  43. // These are invalid inputs that can not be parsed regardless of the format
  44. // used (they are neither valid negative or non-negative values).
  45. const char* kInvalidParseTests[] = {
  46. "", "-", "--", "23-", "134-34", "- ", " ", "+42",
  47. " 123", "123 ", "123\n", "0xFF", "-0xFF", "0x11", "-0x11", "x11",
  48. "-x11", "F11", "-F11", "AF", "-AF", "0AF", "0.0", "13.",
  49. "13,000", "13.000", "13/5", "Inf", "NaN", "null", "dog",
  50. };
  51. // This wrapper calls func() and expects the result to match |expected_output|.
  52. template <typename OutputType, typename ParseFunc, typename ExpectationType>
  53. void ExpectParseIntSuccess(ParseFunc func,
  54. const base::StringPiece& input,
  55. ParseIntFormat format,
  56. ExpectationType expected_output) {
  57. // Try parsing without specifying an error output - expecting success.
  58. OutputType parsed_number1;
  59. EXPECT_TRUE(func(input, format, &parsed_number1, nullptr))
  60. << "Failed to parse: " << input;
  61. EXPECT_EQ(static_cast<OutputType>(expected_output), parsed_number1);
  62. // Try parsing with an error output - expecting success.
  63. ParseIntError kBogusError = static_cast<ParseIntError>(19);
  64. ParseIntError error = kBogusError;
  65. OutputType parsed_number2;
  66. EXPECT_TRUE(func(input, format, &parsed_number2, &error))
  67. << "Failed to parse: " << input;
  68. EXPECT_EQ(static_cast<OutputType>(expected_output), parsed_number2);
  69. // Check that the error output was not written to.
  70. EXPECT_EQ(kBogusError, error);
  71. }
  72. // This wrapper calls func() and expects the failure to match |expected_error|.
  73. template <typename OutputType, typename ParseFunc>
  74. void ExpectParseIntFailure(ParseFunc func,
  75. const base::StringPiece& input,
  76. ParseIntFormat format,
  77. ParseIntError expected_error) {
  78. const OutputType kBogusOutput(23614);
  79. // Try parsing without specifying an error output - expecting failure.
  80. OutputType parsed_number1 = kBogusOutput;
  81. EXPECT_FALSE(func(input, format, &parsed_number1, nullptr))
  82. << "Succeded parsing: " << input;
  83. EXPECT_EQ(kBogusOutput, parsed_number1)
  84. << "Modified output when failed parsing";
  85. // Try parsing with an error output - expecting failure.
  86. OutputType parsed_number2 = kBogusOutput;
  87. ParseIntError error;
  88. EXPECT_FALSE(func(input, format, &parsed_number2, &error))
  89. << "Succeded parsing: " << input;
  90. EXPECT_EQ(kBogusOutput, parsed_number2)
  91. << "Modified output when failed parsing";
  92. EXPECT_EQ(expected_error, error);
  93. }
  94. // Common tests for both ParseInt*() and ParseUint*()
  95. //
  96. // When testing ParseUint*() the |format| parameter is not applicable and
  97. // should be passed as NON_NEGATIVE.
  98. template <typename T, typename ParseFunc>
  99. void TestParseIntUsingFormat(ParseFunc func, ParseIntFormat format) {
  100. // Test valid non-negative inputs
  101. for (const auto& test : kValidNonNegativeTests) {
  102. ExpectParseIntSuccess<T>(func, test.input, format, test.expected_output);
  103. }
  104. // Test invalid inputs (invalid regardless of parsing format)
  105. for (auto* input : kInvalidParseTests) {
  106. ExpectParseIntFailure<T>(func, input, format, ParseIntError::FAILED_PARSE);
  107. }
  108. // Test valid negative inputs (constructed from the valid non-negative test
  109. // cases).
  110. for (const auto& test : kValidNonNegativeTests) {
  111. std::string negative_input = std::string("-") + test.input;
  112. int expected_negative_output = -test.expected_output;
  113. // The result depends on the format.
  114. if (format == ParseIntFormat::NON_NEGATIVE) {
  115. ExpectParseIntFailure<T>(func, negative_input, format,
  116. ParseIntError::FAILED_PARSE);
  117. } else {
  118. ExpectParseIntSuccess<T>(func, negative_input, format,
  119. expected_negative_output);
  120. }
  121. }
  122. // Test parsing the largest possible value for output type.
  123. {
  124. const T value = std::numeric_limits<T>::max();
  125. ExpectParseIntSuccess<T>(func, base::NumberToString(value), format, value);
  126. }
  127. // Test parsing a number one larger than the output type can accomodate
  128. // (overflow).
  129. ExpectParseIntFailure<T>(func, CreateOverflowString<T>(), format,
  130. ParseIntError::FAILED_OVERFLOW);
  131. // Test parsing a number at least as large as the output allows AND contains
  132. // garbage at the end. This exercises an interesting internal quirk of
  133. // base::StringToInt*(), in that its result cannot distinguish this case
  134. // from overflow.
  135. ExpectParseIntFailure<T>(
  136. func, base::NumberToString(std::numeric_limits<T>::max()) + " ", format,
  137. ParseIntError::FAILED_PARSE);
  138. ExpectParseIntFailure<T>(func, CreateOverflowString<T>() + " ", format,
  139. ParseIntError::FAILED_PARSE);
  140. // Test parsing the smallest possible value for output type. Don't do the
  141. // test for unsigned types since the smallest number 0 is tested elsewhere.
  142. if (std::numeric_limits<T>::is_signed) {
  143. const T value = std::numeric_limits<T>::min();
  144. std::string str_value = base::NumberToString(value);
  145. // The minimal value is necessarily negative, since this function is
  146. // testing only signed output types.
  147. if (format == ParseIntFormat::NON_NEGATIVE) {
  148. ExpectParseIntFailure<T>(func, str_value, format,
  149. ParseIntError::FAILED_PARSE);
  150. } else {
  151. ExpectParseIntSuccess<T>(func, str_value, format, value);
  152. }
  153. }
  154. // Test parsing a number one less than the output type can accomodate
  155. // (underflow).
  156. if (format == ParseIntFormat::OPTIONALLY_NEGATIVE) {
  157. ExpectParseIntFailure<T>(func, CreateUnderflowString<T>(),
  158. ParseIntFormat::OPTIONALLY_NEGATIVE,
  159. ParseIntError::FAILED_UNDERFLOW);
  160. }
  161. // Test parsing a string that contains a valid number followed by a NUL
  162. // character.
  163. ExpectParseIntFailure<T>(func, base::StringPiece("123\0", 4), format,
  164. ParseIntError::FAILED_PARSE);
  165. }
  166. // Common tests to run for each of the versions of ParseInt*().
  167. //
  168. // The |func| parameter should be a function pointer to the particular
  169. // ParseInt*() function to test.
  170. template <typename T, typename ParseFunc>
  171. void TestParseInt(ParseFunc func) {
  172. // Test using each of the possible formats.
  173. ParseIntFormat kFormats[] = {ParseIntFormat::NON_NEGATIVE,
  174. ParseIntFormat::OPTIONALLY_NEGATIVE};
  175. for (const auto& format : kFormats) {
  176. TestParseIntUsingFormat<T>(func, format);
  177. }
  178. }
  179. // Common tests to run for each of the versions of ParseUint*().
  180. //
  181. // The |func| parameter should be a function pointer to the particular
  182. // ParseUint*() function to test.
  183. template <typename T, typename ParseFunc>
  184. void TestParseUint(ParseFunc func) {
  185. // TestParseIntUsingFormat() expects a functor that has a |format|
  186. // parameter. For ParseUint*() there is no such parameter. For all intents
  187. // and purposes can just fix it to NON_NEGATIVE and re-use that test driver.
  188. auto func_adapter = [&func](const base::StringPiece& input,
  189. ParseIntFormat format, T* output,
  190. ParseIntError* optional_error) {
  191. EXPECT_EQ(ParseIntFormat::NON_NEGATIVE, format);
  192. return func(input, output, optional_error);
  193. };
  194. TestParseIntUsingFormat<T>(func_adapter, ParseIntFormat::NON_NEGATIVE);
  195. }
  196. TEST(ParseNumberTest, ParseInt32) {
  197. TestParseInt<int32_t>(ParseInt32);
  198. }
  199. TEST(ParseNumberTest, ParseInt64) {
  200. TestParseInt<int64_t>(ParseInt64);
  201. }
  202. TEST(ParseNumberTest, ParseUint32) {
  203. TestParseUint<uint32_t>(ParseUint32);
  204. }
  205. TEST(ParseNumberTest, ParseUint64) {
  206. TestParseUint<uint64_t>(ParseUint64);
  207. }
  208. } // namespace
  209. } // namespace net