1 //===-- Unittests for strtoull --------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/stdlib/strtoull.h" 10 11 #include <errno.h> 12 #include <limits.h> 13 #include <stddef.h> 14 15 #include "utils/UnitTest/Test.h" 16 17 TEST(LlvmLibcStrToULLTest, InvalidBase) { 18 const char *ten = "10"; 19 errno = 0; 20 ASSERT_EQ(__llvm_libc::strtoull(ten, nullptr, -1), 0ull); 21 ASSERT_EQ(errno, EINVAL); 22 } 23 24 TEST(LlvmLibcStrToULLTest, CleanBaseTenDecode) { 25 char *str_end = nullptr; 26 27 const char *ten = "10"; 28 errno = 0; 29 ASSERT_EQ(__llvm_libc::strtoull(ten, &str_end, 10), 10ull); 30 ASSERT_EQ(errno, 0); 31 EXPECT_EQ(str_end - ten, ptrdiff_t(2)); 32 errno = 0; 33 ASSERT_EQ(__llvm_libc::strtoull(ten, nullptr, 10), 10ull); 34 ASSERT_EQ(errno, 0); 35 36 const char *hundred = "100"; 37 errno = 0; 38 ASSERT_EQ(__llvm_libc::strtoull(hundred, &str_end, 10), 100ull); 39 ASSERT_EQ(errno, 0); 40 EXPECT_EQ(str_end - hundred, ptrdiff_t(3)); 41 42 const char *negative = "-100"; 43 errno = 0; 44 ASSERT_EQ(__llvm_libc::strtoull(negative, &str_end, 10), -(100ull)); 45 ASSERT_EQ(errno, 0); 46 EXPECT_EQ(str_end - negative, ptrdiff_t(4)); 47 48 const char *big_number = "123456789012345"; 49 errno = 0; 50 ASSERT_EQ(__llvm_libc::strtoull(big_number, &str_end, 10), 51 123456789012345ull); 52 ASSERT_EQ(errno, 0); 53 EXPECT_EQ(str_end - big_number, ptrdiff_t(15)); 54 55 const char *unsigned_long_long_max_number = "18446744073709551615"; 56 errno = 0; 57 ASSERT_EQ(__llvm_libc::strtoull(unsigned_long_long_max_number, &str_end, 10), 58 18446744073709551615ull); 59 ASSERT_EQ(errno, 0); 60 EXPECT_EQ(str_end - unsigned_long_long_max_number, ptrdiff_t(20)); 61 62 const char *too_big_number = "123456789012345678901"; 63 errno = 0; 64 ASSERT_EQ(__llvm_libc::strtoull(too_big_number, &str_end, 10), ULLONG_MAX); 65 ASSERT_EQ(errno, ERANGE); 66 EXPECT_EQ(str_end - too_big_number, ptrdiff_t(21)); 67 68 const char *too_big_negative_number = "-123456789012345678901"; 69 errno = 0; 70 ASSERT_EQ(__llvm_libc::strtoull(too_big_negative_number, &str_end, 10), 71 ULLONG_MAX); 72 ASSERT_EQ(errno, ERANGE); 73 EXPECT_EQ(str_end - too_big_negative_number, ptrdiff_t(22)); 74 75 const char *long_number_range_test = 76 "10000000000000000000000000000000000000000000000000"; 77 errno = 0; 78 ASSERT_EQ(__llvm_libc::strtoull(long_number_range_test, &str_end, 10), 79 ULLONG_MAX); 80 ASSERT_EQ(errno, ERANGE); 81 EXPECT_EQ(str_end - long_number_range_test, ptrdiff_t(50)); 82 } 83 84 TEST(LlvmLibcStrToULLTest, MessyBaseTenDecode) { 85 char *str_end = nullptr; 86 87 const char *spaces_before = " 10"; 88 errno = 0; 89 ASSERT_EQ(__llvm_libc::strtoull(spaces_before, &str_end, 10), 10ull); 90 ASSERT_EQ(errno, 0); 91 EXPECT_EQ(str_end - spaces_before, ptrdiff_t(7)); 92 93 const char *spaces_after = "10 "; 94 errno = 0; 95 ASSERT_EQ(__llvm_libc::strtoull(spaces_after, &str_end, 10), 10ull); 96 ASSERT_EQ(errno, 0); 97 EXPECT_EQ(str_end - spaces_after, ptrdiff_t(2)); 98 99 const char *word_before = "word10"; 100 errno = 0; 101 ASSERT_EQ(__llvm_libc::strtoull(word_before, &str_end, 10), 0ull); 102 ASSERT_EQ(errno, 0); 103 EXPECT_EQ(str_end - word_before, ptrdiff_t(0)); 104 105 const char *word_after = "10word"; 106 errno = 0; 107 ASSERT_EQ(__llvm_libc::strtoull(word_after, &str_end, 10), 10ull); 108 ASSERT_EQ(errno, 0); 109 EXPECT_EQ(str_end - word_after, ptrdiff_t(2)); 110 111 const char *two_numbers = "10 999"; 112 errno = 0; 113 ASSERT_EQ(__llvm_libc::strtoull(two_numbers, &str_end, 10), 10ull); 114 ASSERT_EQ(errno, 0); 115 EXPECT_EQ(str_end - two_numbers, ptrdiff_t(2)); 116 117 const char *two_signs = "--10 999"; 118 errno = 0; 119 ASSERT_EQ(__llvm_libc::strtoull(two_signs, &str_end, 10), 0ull); 120 ASSERT_EQ(errno, 0); 121 EXPECT_EQ(str_end - two_signs, ptrdiff_t(0)); 122 123 const char *sign_before = "+2=4"; 124 errno = 0; 125 ASSERT_EQ(__llvm_libc::strtoull(sign_before, &str_end, 10), 2ull); 126 ASSERT_EQ(errno, 0); 127 EXPECT_EQ(str_end - sign_before, ptrdiff_t(2)); 128 129 const char *sign_after = "2+2=4"; 130 errno = 0; 131 ASSERT_EQ(__llvm_libc::strtoull(sign_after, &str_end, 10), 2ull); 132 ASSERT_EQ(errno, 0); 133 EXPECT_EQ(str_end - sign_after, ptrdiff_t(1)); 134 135 const char *tab_before = "\t10"; 136 errno = 0; 137 ASSERT_EQ(__llvm_libc::strtoull(tab_before, &str_end, 10), 10ull); 138 ASSERT_EQ(errno, 0); 139 EXPECT_EQ(str_end - tab_before, ptrdiff_t(3)); 140 141 const char *all_together = "\t -12345and+67890"; 142 errno = 0; 143 ASSERT_EQ(__llvm_libc::strtoull(all_together, &str_end, 10), -(12345ull)); 144 ASSERT_EQ(errno, 0); 145 EXPECT_EQ(str_end - all_together, ptrdiff_t(9)); 146 147 const char *just_spaces = " "; 148 errno = 0; 149 ASSERT_EQ(__llvm_libc::strtoull(just_spaces, &str_end, 10), 0ull); 150 ASSERT_EQ(errno, 0); 151 EXPECT_EQ(str_end - just_spaces, ptrdiff_t(0)); 152 153 const char *just_space_and_sign = " +"; 154 errno = 0; 155 ASSERT_EQ(__llvm_libc::strtoull(just_space_and_sign, &str_end, 10), 0ull); 156 ASSERT_EQ(errno, 0); 157 EXPECT_EQ(str_end - just_space_and_sign, ptrdiff_t(0)); 158 } 159 160 static char int_to_b36_char(int input) { 161 if (input < 0 || input > 36) 162 return '0'; 163 if (input < 10) 164 return static_cast<char>('0' + input); 165 return static_cast<char>('A' + input - 10); 166 } 167 168 TEST(LlvmLibcStrToULLTest, DecodeInOtherBases) { 169 char small_string[4] = {'\0', '\0', '\0', '\0'}; 170 for (int base = 2; base <= 36; ++base) { 171 for (int first_digit = 0; first_digit <= 36; ++first_digit) { 172 small_string[0] = int_to_b36_char(first_digit); 173 if (first_digit < base) { 174 errno = 0; 175 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 176 static_cast<unsigned long long int>(first_digit)); 177 ASSERT_EQ(errno, 0); 178 } else { 179 errno = 0; 180 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 0ull); 181 ASSERT_EQ(errno, 0); 182 } 183 } 184 } 185 186 for (int base = 2; base <= 36; ++base) { 187 for (int first_digit = 0; first_digit <= 36; ++first_digit) { 188 small_string[0] = int_to_b36_char(first_digit); 189 for (int second_digit = 0; second_digit <= 36; ++second_digit) { 190 small_string[1] = int_to_b36_char(second_digit); 191 if (first_digit < base && second_digit < base) { 192 errno = 0; 193 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 194 static_cast<unsigned long long int>(second_digit + 195 (first_digit * base))); 196 ASSERT_EQ(errno, 0); 197 } else if (first_digit < base) { 198 errno = 0; 199 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 200 static_cast<unsigned long long int>(first_digit)); 201 ASSERT_EQ(errno, 0); 202 } else { 203 errno = 0; 204 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 0ull); 205 ASSERT_EQ(errno, 0); 206 } 207 } 208 } 209 } 210 211 for (int base = 2; base <= 36; ++base) { 212 for (int first_digit = 0; first_digit <= 36; ++first_digit) { 213 small_string[0] = int_to_b36_char(first_digit); 214 for (int second_digit = 0; second_digit <= 36; ++second_digit) { 215 small_string[1] = int_to_b36_char(second_digit); 216 for (int third_digit = 0; third_digit <= 36; ++third_digit) { 217 small_string[2] = int_to_b36_char(third_digit); 218 219 if (first_digit < base && second_digit < base && third_digit < base) { 220 errno = 0; 221 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 222 static_cast<unsigned long long int>( 223 third_digit + (second_digit * base) + 224 (first_digit * base * base))); 225 ASSERT_EQ(errno, 0); 226 } else if (first_digit < base && second_digit < base) { 227 errno = 0; 228 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 229 static_cast<unsigned long long int>( 230 second_digit + (first_digit * base))); 231 ASSERT_EQ(errno, 0); 232 } else if (first_digit < base) { 233 // if the base is 16 there is a special case for the prefix 0X. 234 // The number is treated as a one digit hexadecimal. 235 if (base == 16 && first_digit == 0 && second_digit == 33) { 236 if (third_digit < base) { 237 errno = 0; 238 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 239 static_cast<unsigned long long int>(third_digit)); 240 ASSERT_EQ(errno, 0); 241 } else { 242 errno = 0; 243 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 244 0ull); 245 ASSERT_EQ(errno, 0); 246 } 247 } else { 248 errno = 0; 249 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 250 static_cast<unsigned long long int>(first_digit)); 251 ASSERT_EQ(errno, 0); 252 } 253 } else { 254 errno = 0; 255 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 0ull); 256 ASSERT_EQ(errno, 0); 257 } 258 } 259 } 260 } 261 } 262 } 263 264 TEST(LlvmLibcStrToULLTest, CleanBaseSixteenDecode) { 265 char *str_end = nullptr; 266 267 const char *no_prefix = "123abc"; 268 errno = 0; 269 ASSERT_EQ(__llvm_libc::strtoull(no_prefix, &str_end, 16), 0x123abcull); 270 ASSERT_EQ(errno, 0); 271 EXPECT_EQ(str_end - no_prefix, ptrdiff_t(6)); 272 273 const char *yes_prefix = "0x456def"; 274 errno = 0; 275 ASSERT_EQ(__llvm_libc::strtoull(yes_prefix, &str_end, 16), 0x456defull); 276 ASSERT_EQ(errno, 0); 277 EXPECT_EQ(str_end - yes_prefix, ptrdiff_t(8)); 278 279 const char *letter_after_prefix = "0xabc123"; 280 errno = 0; 281 ASSERT_EQ(__llvm_libc::strtoull(letter_after_prefix, &str_end, 16), 282 0xabc123ull); 283 ASSERT_EQ(errno, 0); 284 EXPECT_EQ(str_end - letter_after_prefix, ptrdiff_t(8)); 285 } 286 287 TEST(LlvmLibcStrToULLTest, MessyBaseSixteenDecode) { 288 char *str_end = nullptr; 289 290 const char *just_prefix = "0x"; 291 errno = 0; 292 ASSERT_EQ(__llvm_libc::strtoull(just_prefix, &str_end, 16), 0ull); 293 ASSERT_EQ(errno, 0); 294 EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1)); 295 296 errno = 0; 297 ASSERT_EQ(__llvm_libc::strtoull(just_prefix, &str_end, 0), 0ull); 298 ASSERT_EQ(errno, 0); 299 EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1)); 300 301 const char *prefix_with_x_after = "0xx"; 302 errno = 0; 303 ASSERT_EQ(__llvm_libc::strtoull(prefix_with_x_after, &str_end, 16), 0ull); 304 ASSERT_EQ(errno, 0); 305 EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1)); 306 307 errno = 0; 308 ASSERT_EQ(__llvm_libc::strtoull(prefix_with_x_after, &str_end, 0), 0ull); 309 ASSERT_EQ(errno, 0); 310 EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1)); 311 } 312 313 TEST(LlvmLibcStrToULLTest, AutomaticBaseSelection) { 314 char *str_end = nullptr; 315 316 const char *base_ten = "12345"; 317 errno = 0; 318 ASSERT_EQ(__llvm_libc::strtoull(base_ten, &str_end, 0), 12345ull); 319 ASSERT_EQ(errno, 0); 320 EXPECT_EQ(str_end - base_ten, ptrdiff_t(5)); 321 322 const char *base_sixteen_no_prefix = "123abc"; 323 errno = 0; 324 ASSERT_EQ(__llvm_libc::strtoull(base_sixteen_no_prefix, &str_end, 0), 123ull); 325 ASSERT_EQ(errno, 0); 326 EXPECT_EQ(str_end - base_sixteen_no_prefix, ptrdiff_t(3)); 327 328 const char *base_sixteen_with_prefix = "0x456def"; 329 errno = 0; 330 ASSERT_EQ(__llvm_libc::strtoull(base_sixteen_with_prefix, &str_end, 0), 331 0x456defull); 332 ASSERT_EQ(errno, 0); 333 EXPECT_EQ(str_end - base_sixteen_with_prefix, ptrdiff_t(8)); 334 335 const char *base_eight_with_prefix = "012345"; 336 errno = 0; 337 ASSERT_EQ(__llvm_libc::strtoull(base_eight_with_prefix, &str_end, 0), 338 012345ull); 339 ASSERT_EQ(errno, 0); 340 EXPECT_EQ(str_end - base_eight_with_prefix, ptrdiff_t(6)); 341 342 const char *just_zero = "0"; 343 errno = 0; 344 ASSERT_EQ(__llvm_libc::strtoull(just_zero, &str_end, 0), 0ull); 345 ASSERT_EQ(errno, 0); 346 EXPECT_EQ(str_end - just_zero, ptrdiff_t(1)); 347 348 const char *just_zero_x = "0x"; 349 errno = 0; 350 ASSERT_EQ(__llvm_libc::strtoull(just_zero_x, &str_end, 0), 0ull); 351 ASSERT_EQ(errno, 0); 352 EXPECT_EQ(str_end - just_zero_x, ptrdiff_t(1)); 353 354 const char *just_zero_eight = "08"; 355 errno = 0; 356 ASSERT_EQ(__llvm_libc::strtoull(just_zero_eight, &str_end, 0), 0ull); 357 ASSERT_EQ(errno, 0); 358 EXPECT_EQ(str_end - just_zero_eight, ptrdiff_t(1)); 359 } 360