1 //===-- Unittests for strtol ---------------------------------------------===// 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/strtol.h" 10 11 #include "utils/UnitTest/Test.h" 12 13 #include <errno.h> 14 #include <limits.h> 15 #include <stddef.h> 16 17 TEST(LlvmLibcStrToLTest, InvalidBase) { 18 const char *ten = "10"; 19 errno = 0; 20 ASSERT_EQ(__llvm_libc::strtol(ten, nullptr, -1), 0l); 21 ASSERT_EQ(errno, EINVAL); 22 } 23 24 TEST(LlvmLibcStrToLTest, CleanBaseTenDecode) { 25 char *str_end = nullptr; 26 27 const char *ten = "10"; 28 errno = 0; 29 ASSERT_EQ(__llvm_libc::strtol(ten, &str_end, 10), 10l); 30 ASSERT_EQ(errno, 0); 31 EXPECT_EQ(str_end - ten, ptrdiff_t(2)); 32 33 errno = 0; 34 ASSERT_EQ(__llvm_libc::strtol(ten, nullptr, 10), 10l); 35 ASSERT_EQ(errno, 0); 36 37 const char *hundred = "100"; 38 errno = 0; 39 ASSERT_EQ(__llvm_libc::strtol(hundred, &str_end, 10), 100l); 40 ASSERT_EQ(errno, 0); 41 EXPECT_EQ(str_end - hundred, ptrdiff_t(3)); 42 43 const char *negative = "-100"; 44 errno = 0; 45 ASSERT_EQ(__llvm_libc::strtol(negative, &str_end, 10), -100l); 46 ASSERT_EQ(errno, 0); 47 EXPECT_EQ(str_end - negative, ptrdiff_t(4)); 48 49 const char *big_number = "1234567890"; 50 errno = 0; 51 ASSERT_EQ(__llvm_libc::strtol(big_number, &str_end, 10), 1234567890l); 52 ASSERT_EQ(errno, 0); 53 EXPECT_EQ(str_end - big_number, ptrdiff_t(10)); 54 55 const char *big_negative_number = "-1234567890"; 56 errno = 0; 57 ASSERT_EQ(__llvm_libc::strtol(big_negative_number, &str_end, 10), 58 -1234567890l); 59 ASSERT_EQ(errno, 0); 60 EXPECT_EQ(str_end - big_negative_number, ptrdiff_t(11)); 61 62 const char *too_big_number = "123456789012345678901"; 63 errno = 0; 64 ASSERT_EQ(__llvm_libc::strtol(too_big_number, &str_end, 10), LONG_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::strtol(too_big_negative_number, &str_end, 10), 71 LONG_MIN); 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::strtol(long_number_range_test, &str_end, 10), 79 LONG_MAX); 80 ASSERT_EQ(errno, ERANGE); 81 EXPECT_EQ(str_end - long_number_range_test, ptrdiff_t(50)); 82 } 83 84 TEST(LlvmLibcStrToLTest, MessyBaseTenDecode) { 85 char *str_end = nullptr; 86 87 const char *spaces_before = " 10"; 88 errno = 0; 89 ASSERT_EQ(__llvm_libc::strtol(spaces_before, &str_end, 10), 10l); 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::strtol(spaces_after, &str_end, 10), 10l); 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::strtol(word_before, &str_end, 10), 0l); 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::strtol(word_after, &str_end, 10), 10l); 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::strtol(two_numbers, &str_end, 10), 10l); 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::strtol(two_signs, &str_end, 10), 0l); 120 ASSERT_EQ(errno, 0); 121 EXPECT_EQ(str_end - two_signs, ptrdiff_t(1)); 122 123 const char *sign_before = "+2=4"; 124 errno = 0; 125 ASSERT_EQ(__llvm_libc::strtol(sign_before, &str_end, 10), 2l); 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::strtol(sign_after, &str_end, 10), 2l); 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::strtol(tab_before, &str_end, 10), 10l); 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::strtol(all_together, &str_end, 10), -12345l); 144 ASSERT_EQ(errno, 0); 145 EXPECT_EQ(str_end - all_together, ptrdiff_t(9)); 146 } 147 148 static char int_to_b36_char(int input) { 149 if (input < 0 || input > 36) 150 return '0'; 151 if (input < 10) 152 return static_cast<char>('0' + input); 153 return static_cast<char>('A' + input - 10); 154 } 155 156 TEST(LlvmLibcStrToLTest, DecodeInOtherBases) { 157 char small_string[4] = {'\0', '\0', '\0', '\0'}; 158 for (int base = 2; base <= 36; ++base) { 159 for (int first_digit = 0; first_digit <= 36; ++first_digit) { 160 small_string[0] = int_to_b36_char(first_digit); 161 if (first_digit < base) { 162 errno = 0; 163 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 164 static_cast<long int>(first_digit)); 165 ASSERT_EQ(errno, 0); 166 } else { 167 errno = 0; 168 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 0l); 169 ASSERT_EQ(errno, 0); 170 } 171 } 172 } 173 174 for (int base = 2; base <= 36; ++base) { 175 for (int first_digit = 0; first_digit <= 36; ++first_digit) { 176 small_string[0] = int_to_b36_char(first_digit); 177 for (int second_digit = 0; second_digit <= 36; ++second_digit) { 178 small_string[1] = int_to_b36_char(second_digit); 179 if (first_digit < base && second_digit < base) { 180 errno = 0; 181 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 182 static_cast<long int>(second_digit + (first_digit * base))); 183 ASSERT_EQ(errno, 0); 184 } else if (first_digit < base) { 185 errno = 0; 186 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 187 static_cast<long int>(first_digit)); 188 ASSERT_EQ(errno, 0); 189 } else { 190 errno = 0; 191 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 0l); 192 ASSERT_EQ(errno, 0); 193 } 194 } 195 } 196 } 197 198 for (int base = 2; base <= 36; ++base) { 199 for (int first_digit = 0; first_digit <= 36; ++first_digit) { 200 small_string[0] = int_to_b36_char(first_digit); 201 for (int second_digit = 0; second_digit <= 36; ++second_digit) { 202 small_string[1] = int_to_b36_char(second_digit); 203 for (int third_digit = 0; third_digit <= 36; ++third_digit) { 204 small_string[2] = int_to_b36_char(third_digit); 205 206 if (first_digit < base && second_digit < base && third_digit < base) { 207 errno = 0; 208 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 209 static_cast<long int>(third_digit + 210 (second_digit * base) + 211 (first_digit * base * base))); 212 ASSERT_EQ(errno, 0); 213 } else if (first_digit < base && second_digit < base) { 214 errno = 0; 215 ASSERT_EQ( 216 __llvm_libc::strtol(small_string, nullptr, base), 217 static_cast<long int>(second_digit + (first_digit * base))); 218 ASSERT_EQ(errno, 0); 219 } else if (first_digit < base) { 220 // if the base is 16 there is a special case for the prefix 0X. 221 // The number is treated as a one digit hexadecimal. 222 if (base == 16 && first_digit == 0 && second_digit == 33) { 223 if (third_digit < base) { 224 errno = 0; 225 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 226 static_cast<long int>(third_digit)); 227 ASSERT_EQ(errno, 0); 228 } else { 229 errno = 0; 230 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 0l); 231 ASSERT_EQ(errno, 0); 232 } 233 } else { 234 errno = 0; 235 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 236 static_cast<long int>(first_digit)); 237 ASSERT_EQ(errno, 0); 238 } 239 } else { 240 errno = 0; 241 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 0l); 242 ASSERT_EQ(errno, 0); 243 } 244 } 245 } 246 } 247 } 248 } 249 250 TEST(LlvmLibcStrToLTest, CleanBaseSixteenDecode) { 251 char *str_end = nullptr; 252 253 const char *no_prefix = "123abc"; 254 errno = 0; 255 ASSERT_EQ(__llvm_libc::strtol(no_prefix, &str_end, 16), 0x123abcl); 256 ASSERT_EQ(errno, 0); 257 EXPECT_EQ(str_end - no_prefix, ptrdiff_t(6)); 258 259 const char *yes_prefix = "0x456def"; 260 errno = 0; 261 ASSERT_EQ(__llvm_libc::strtol(yes_prefix, &str_end, 16), 0x456defl); 262 ASSERT_EQ(errno, 0); 263 EXPECT_EQ(str_end - yes_prefix, ptrdiff_t(8)); 264 } 265 266 TEST(LlvmLibcStrToLTest, AutomaticBaseSelection) { 267 char *str_end = nullptr; 268 269 const char *base_ten = "12345"; 270 errno = 0; 271 ASSERT_EQ(__llvm_libc::strtol(base_ten, &str_end, 0), 12345l); 272 ASSERT_EQ(errno, 0); 273 EXPECT_EQ(str_end - base_ten, ptrdiff_t(5)); 274 275 const char *base_sixteen_no_prefix = "123abc"; 276 errno = 0; 277 ASSERT_EQ(__llvm_libc::strtol(base_sixteen_no_prefix, &str_end, 0), 123l); 278 ASSERT_EQ(errno, 0); 279 EXPECT_EQ(str_end - base_sixteen_no_prefix, ptrdiff_t(3)); 280 281 const char *base_sixteen_with_prefix = "0x456def"; 282 errno = 0; 283 ASSERT_EQ(__llvm_libc::strtol(base_sixteen_with_prefix, &str_end, 0), 284 0x456defl); 285 ASSERT_EQ(errno, 0); 286 EXPECT_EQ(str_end - base_sixteen_with_prefix, ptrdiff_t(8)); 287 288 const char *base_eight_with_prefix = "012345"; 289 errno = 0; 290 ASSERT_EQ(__llvm_libc::strtol(base_eight_with_prefix, &str_end, 0), 012345l); 291 ASSERT_EQ(errno, 0); 292 EXPECT_EQ(str_end - base_eight_with_prefix, ptrdiff_t(6)); 293 } 294