string_number_conversion_test.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. // Copyright 2014 The Crashpad Authors. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "util/stdlib/string_number_conversion.h"
  15. #include <sys/types.h>
  16. #include <limits>
  17. #include "base/macros.h"
  18. #include "gtest/gtest.h"
  19. namespace crashpad {
  20. namespace test {
  21. namespace {
  22. TEST(StringNumberConversion, StringToInt) {
  23. static constexpr struct {
  24. const char* string;
  25. bool valid;
  26. int value;
  27. } kTestData[] = {
  28. {"", false, 0},
  29. {"0", true, 0},
  30. {"1", true, 1},
  31. {"2147483647", true, std::numeric_limits<int>::max()},
  32. {"2147483648", false, 0},
  33. {"4294967295", false, 0},
  34. {"4294967296", false, 0},
  35. {"-1", true, -1},
  36. {"-2147483648", true, std::numeric_limits<int>::min()},
  37. {"-2147483649", false, 0},
  38. {"00", true, 0},
  39. {"01", true, 1},
  40. {"-01", true, -1},
  41. {"+2", true, 2},
  42. {"0x10", true, 16},
  43. {"-0x10", true, -16},
  44. {"+0x20", true, 32},
  45. {"0xf", true, 15},
  46. {"0xg", false, 0},
  47. {"0x7fffffff", true, std::numeric_limits<int>::max()},
  48. {"0x7FfFfFfF", true, std::numeric_limits<int>::max()},
  49. {"0x80000000", false, 0},
  50. {"0xFFFFFFFF", false, 0},
  51. {"-0x7fffffff", true, -2147483647},
  52. {"-0x80000000", true, std::numeric_limits<int>::min()},
  53. {"-0x80000001", false, 0},
  54. {"-0xffffffff", false, 0},
  55. {"0x100000000", false, 0},
  56. {"0xabcdef", true, 11259375},
  57. {"010", true, 8},
  58. {"-010", true, -8},
  59. {"+020", true, 16},
  60. {"07", true, 7},
  61. {"08", false, 0},
  62. {" 0", false, 0},
  63. {"0 ", false, 0},
  64. {" 0 ", false, 0},
  65. {" 1", false, 0},
  66. {"1 ", false, 0},
  67. {" 1 ", false, 0},
  68. {"a2", false, 0},
  69. {"2a", false, 0},
  70. {"2a2", false, 0},
  71. {".0", false, 0},
  72. {".1", false, 0},
  73. {"-.2", false, 0},
  74. {"+.3", false, 0},
  75. {"1.23", false, 0},
  76. {"-273.15", false, 0},
  77. {"+98.6", false, 0},
  78. {"1e1", false, 0},
  79. {"1E1", false, 0},
  80. {"0x123p4", false, 0},
  81. {"infinity", false, 0},
  82. {"NaN", false, 0},
  83. {"-9223372036854775810", false, 0},
  84. {"-9223372036854775809", false, 0},
  85. {"9223372036854775808", false, 0},
  86. {"9223372036854775809", false, 0},
  87. {"18446744073709551615", false, 0},
  88. {"18446744073709551616", false, 0},
  89. };
  90. for (size_t index = 0; index < arraysize(kTestData); ++index) {
  91. int value;
  92. bool valid = StringToNumber(kTestData[index].string, &value);
  93. if (kTestData[index].valid) {
  94. EXPECT_TRUE(valid) << "index " << index << ", string "
  95. << kTestData[index].string;
  96. if (valid) {
  97. EXPECT_EQ(value, kTestData[index].value)
  98. << "index " << index << ", string " << kTestData[index].string;
  99. }
  100. } else {
  101. EXPECT_FALSE(valid) << "index " << index << ", string "
  102. << kTestData[index].string << ", value " << value;
  103. }
  104. }
  105. // Ensure that embedded NUL characters are treated as bad input. The string
  106. // is split to avoid MSVC warning:
  107. // "decimal digit terminates octal escape sequence".
  108. static constexpr char input[] = "6\000" "6";
  109. base::StringPiece input_string(input, arraysize(input) - 1);
  110. int output;
  111. EXPECT_FALSE(StringToNumber(input_string, &output));
  112. // Ensure that a NUL is not required at the end of the string.
  113. EXPECT_TRUE(StringToNumber(base::StringPiece("66", 1), &output));
  114. EXPECT_EQ(output, 6);
  115. }
  116. TEST(StringNumberConversion, StringToUnsignedInt) {
  117. static constexpr struct {
  118. const char* string;
  119. bool valid;
  120. unsigned int value;
  121. } kTestData[] = {
  122. {"", false, 0},
  123. {"0", true, 0},
  124. {"1", true, 1},
  125. {"2147483647", true, 2147483647},
  126. {"2147483648", true, 2147483648},
  127. {"4294967295", true, std::numeric_limits<unsigned int>::max()},
  128. {"4294967296", false, 0},
  129. {"-1", false, 0},
  130. {"-2147483648", false, 0},
  131. {"-2147483649", false, 0},
  132. {"00", true, 0},
  133. {"01", true, 1},
  134. {"-01", false, 0},
  135. {"+2", true, 2},
  136. {"0x10", true, 16},
  137. {"-0x10", false, 0},
  138. {"+0x20", true, 32},
  139. {"0xf", true, 15},
  140. {"0xg", false, 0},
  141. {"0x7fffffff", true, 0x7fffffff},
  142. {"0x7FfFfFfF", true, 0x7fffffff},
  143. {"0x80000000", true, 0x80000000},
  144. {"0xFFFFFFFF", true, 0xffffffff},
  145. {"-0x7fffffff", false, 0},
  146. {"-0x80000000", false, 0},
  147. {"-0x80000001", false, 0},
  148. {"-0xffffffff", false, 0},
  149. {"0x100000000", false, 0},
  150. {"0xabcdef", true, 11259375},
  151. {"010", true, 8},
  152. {"-010", false, 0},
  153. {"+020", true, 16},
  154. {"07", true, 7},
  155. {"08", false, 0},
  156. {" 0", false, 0},
  157. {"0 ", false, 0},
  158. {" 0 ", false, 0},
  159. {" 1", false, 0},
  160. {"1 ", false, 0},
  161. {" 1 ", false, 0},
  162. {"a2", false, 0},
  163. {"2a", false, 0},
  164. {"2a2", false, 0},
  165. {".0", false, 0},
  166. {".1", false, 0},
  167. {"-.2", false, 0},
  168. {"+.3", false, 0},
  169. {"1.23", false, 0},
  170. {"-273.15", false, 0},
  171. {"+98.6", false, 0},
  172. {"1e1", false, 0},
  173. {"1E1", false, 0},
  174. {"0x123p4", false, 0},
  175. {"infinity", false, 0},
  176. {"NaN", false, 0},
  177. {"-9223372036854775810", false, 0},
  178. {"-9223372036854775809", false, 0},
  179. {"9223372036854775808", false, 0},
  180. {"9223372036854775809", false, 0},
  181. {"18446744073709551615", false, 0},
  182. {"18446744073709551616", false, 0},
  183. };
  184. for (size_t index = 0; index < arraysize(kTestData); ++index) {
  185. unsigned int value;
  186. bool valid = StringToNumber(kTestData[index].string, &value);
  187. if (kTestData[index].valid) {
  188. EXPECT_TRUE(valid) << "index " << index << ", string "
  189. << kTestData[index].string;
  190. if (valid) {
  191. EXPECT_EQ(value, kTestData[index].value)
  192. << "index " << index << ", string " << kTestData[index].string;
  193. }
  194. } else {
  195. EXPECT_FALSE(valid) << "index " << index << ", string "
  196. << kTestData[index].string << ", value " << value;
  197. }
  198. }
  199. // Ensure that embedded NUL characters are treated as bad input. The string
  200. // is split to avoid MSVC warning:
  201. // "decimal digit terminates octal escape sequence".
  202. static constexpr char input[] = "6\000" "6";
  203. base::StringPiece input_string(input, arraysize(input) - 1);
  204. unsigned int output;
  205. EXPECT_FALSE(StringToNumber(input_string, &output));
  206. // Ensure that a NUL is not required at the end of the string.
  207. EXPECT_TRUE(StringToNumber(base::StringPiece("66", 1), &output));
  208. EXPECT_EQ(output, 6u);
  209. }
  210. TEST(StringNumberConversion, StringToInt64) {
  211. static constexpr struct {
  212. const char* string;
  213. bool valid;
  214. int64_t value;
  215. } kTestData[] = {
  216. {"", false, 0},
  217. {"0", true, 0},
  218. {"1", true, 1},
  219. {"2147483647", true, 2147483647},
  220. {"2147483648", true, 2147483648},
  221. {"4294967295", true, 4294967295},
  222. {"4294967296", true, 4294967296},
  223. {"9223372036854775807", true, std::numeric_limits<int64_t>::max()},
  224. {"9223372036854775808", false, 0},
  225. {"18446744073709551615", false, 0},
  226. {"18446744073709551616", false, 0},
  227. {"-1", true, -1},
  228. {"-2147483648", true, INT64_C(-2147483648)},
  229. {"-2147483649", true, INT64_C(-2147483649)},
  230. {"-9223372036854775808", true, std::numeric_limits<int64_t>::min()},
  231. {"-9223372036854775809", false, 0},
  232. {"0x7fffffffffffffff", true, std::numeric_limits<int64_t>::max()},
  233. {"0x8000000000000000", false, 0},
  234. {"0xffffffffffffffff", false, 0},
  235. {"0x10000000000000000", false, 0},
  236. {"-0x7fffffffffffffff", true, -9223372036854775807},
  237. {"-0x8000000000000000", true, std::numeric_limits<int64_t>::min()},
  238. {"-0x8000000000000001", false, 0},
  239. {"0x7Fffffffffffffff", true, std::numeric_limits<int64_t>::max()},
  240. };
  241. for (size_t index = 0; index < arraysize(kTestData); ++index) {
  242. int64_t value;
  243. bool valid = StringToNumber(kTestData[index].string, &value);
  244. if (kTestData[index].valid) {
  245. EXPECT_TRUE(valid) << "index " << index << ", string "
  246. << kTestData[index].string;
  247. if (valid) {
  248. EXPECT_EQ(value, kTestData[index].value)
  249. << "index " << index << ", string " << kTestData[index].string;
  250. }
  251. } else {
  252. EXPECT_FALSE(valid) << "index " << index << ", string "
  253. << kTestData[index].string << ", value " << value;
  254. }
  255. }
  256. }
  257. TEST(StringNumberConversion, StringToUnsignedInt64) {
  258. static constexpr struct {
  259. const char* string;
  260. bool valid;
  261. uint64_t value;
  262. } kTestData[] = {
  263. {"", false, 0},
  264. {"0", true, 0},
  265. {"1", true, 1},
  266. {"2147483647", true, 2147483647},
  267. {"2147483648", true, 2147483648},
  268. {"4294967295", true, 4294967295},
  269. {"4294967296", true, 4294967296},
  270. {"9223372036854775807", true, 9223372036854775807},
  271. {"9223372036854775808", true, 9223372036854775808u},
  272. {"18446744073709551615", true, std::numeric_limits<uint64_t>::max()},
  273. {"18446744073709551616", false, 0},
  274. {"-1", false, 0},
  275. {"-2147483648", false, 0},
  276. {"-2147483649", false, 0},
  277. {"-2147483648", false, 0},
  278. {"-9223372036854775808", false, 0},
  279. {"-9223372036854775809", false, 0},
  280. {"0x7fffffffffffffff", true, 9223372036854775807},
  281. {"0x8000000000000000", true, 9223372036854775808u},
  282. {"0xffffffffffffffff", true, std::numeric_limits<uint64_t>::max()},
  283. {"0x10000000000000000", false, 0},
  284. {"-0x7fffffffffffffff", false, 0},
  285. {"-0x8000000000000000", false, 0},
  286. {"-0x8000000000000001", false, 0},
  287. {"0xFfffffffffffffff", true, std::numeric_limits<uint64_t>::max()},
  288. };
  289. for (size_t index = 0; index < arraysize(kTestData); ++index) {
  290. uint64_t value;
  291. bool valid = StringToNumber(kTestData[index].string, &value);
  292. if (kTestData[index].valid) {
  293. EXPECT_TRUE(valid) << "index " << index << ", string "
  294. << kTestData[index].string;
  295. if (valid) {
  296. EXPECT_EQ(value, kTestData[index].value)
  297. << "index " << index << ", string " << kTestData[index].string;
  298. }
  299. } else {
  300. EXPECT_FALSE(valid) << "index " << index << ", string "
  301. << kTestData[index].string << ", value " << value;
  302. }
  303. }
  304. }
  305. } // namespace
  306. } // namespace test
  307. } // namespace crashpad