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