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 16 TEST(LlvmLibcStrToLTest, InvalidBase) { 17 const char *ten = "10"; 18 errno = 0; 19 ASSERT_EQ(__llvm_libc::strtol(ten, nullptr, -1), 0l); 20 ASSERT_EQ(errno, EINVAL); 21 } 22 23 TEST(LlvmLibcStrToLTest, CleanBaseTenDecode) { 24 char *str_end = nullptr; 25 26 const char *ten = "10"; 27 errno = 0; 28 ASSERT_EQ(__llvm_libc::strtol(ten, &str_end, 10), 10l); 29 ASSERT_EQ(errno, 0); 30 EXPECT_EQ(str_end - ten, 2l); 31 errno = 0; 32 ASSERT_EQ(__llvm_libc::strtol(ten, nullptr, 10), 10l); 33 ASSERT_EQ(errno, 0); 34 35 const char *hundred = "100"; 36 errno = 0; 37 ASSERT_EQ(__llvm_libc::strtol(hundred, &str_end, 10), 100l); 38 ASSERT_EQ(errno, 0); 39 EXPECT_EQ(str_end - hundred, 3l); 40 41 const char *negative = "-100"; 42 errno = 0; 43 ASSERT_EQ(__llvm_libc::strtol(negative, &str_end, 10), -100l); 44 ASSERT_EQ(errno, 0); 45 EXPECT_EQ(str_end - negative, 4l); 46 47 const char *big_number = "123456789012345"; 48 errno = 0; 49 ASSERT_EQ(__llvm_libc::strtol(big_number, &str_end, 10), 123456789012345l); 50 ASSERT_EQ(errno, 0); 51 EXPECT_EQ(str_end - big_number, 15l); 52 53 const char *big_negative_number = "-123456789012345"; 54 errno = 0; 55 ASSERT_EQ(__llvm_libc::strtol(big_negative_number, &str_end, 10), 56 -123456789012345l); 57 ASSERT_EQ(errno, 0); 58 EXPECT_EQ(str_end - big_negative_number, 16l); 59 60 const char *too_big_number = "123456789012345678901"; 61 errno = 0; 62 ASSERT_EQ(__llvm_libc::strtol(too_big_number, &str_end, 10), LONG_MAX); 63 ASSERT_EQ(errno, ERANGE); 64 EXPECT_EQ(str_end - too_big_number, 21l); 65 66 const char *too_big_negative_number = "-123456789012345678901"; 67 errno = 0; 68 ASSERT_EQ(__llvm_libc::strtol(too_big_negative_number, &str_end, 10), 69 LONG_MIN); 70 ASSERT_EQ(errno, ERANGE); 71 EXPECT_EQ(str_end - too_big_negative_number, 22l); 72 73 const char *long_number_range_test = 74 "10000000000000000000000000000000000000000000000000"; 75 errno = 0; 76 ASSERT_EQ(__llvm_libc::strtol(long_number_range_test, &str_end, 10), 77 LONG_MAX); 78 ASSERT_EQ(errno, ERANGE); 79 EXPECT_EQ(str_end - long_number_range_test, 50l); 80 } 81 82 TEST(LlvmLibcStrToLTest, MessyBaseTenDecode) { 83 char *str_end = nullptr; 84 85 const char *spaces_before = " 10"; 86 errno = 0; 87 ASSERT_EQ(__llvm_libc::strtol(spaces_before, &str_end, 10), 10l); 88 ASSERT_EQ(errno, 0); 89 EXPECT_EQ(str_end - spaces_before, 7l); 90 91 const char *spaces_after = "10 "; 92 errno = 0; 93 ASSERT_EQ(__llvm_libc::strtol(spaces_after, &str_end, 10), 10l); 94 ASSERT_EQ(errno, 0); 95 EXPECT_EQ(str_end - spaces_after, 2l); 96 97 const char *word_before = "word10"; 98 errno = 0; 99 ASSERT_EQ(__llvm_libc::strtol(word_before, &str_end, 10), 0l); 100 ASSERT_EQ(errno, 0); 101 EXPECT_EQ(str_end - word_before, 0l); 102 103 const char *word_after = "10word"; 104 errno = 0; 105 ASSERT_EQ(__llvm_libc::strtol(word_after, &str_end, 10), 10l); 106 ASSERT_EQ(errno, 0); 107 EXPECT_EQ(str_end - word_after, 2l); 108 109 const char *two_numbers = "10 999"; 110 errno = 0; 111 ASSERT_EQ(__llvm_libc::strtol(two_numbers, &str_end, 10), 10l); 112 ASSERT_EQ(errno, 0); 113 EXPECT_EQ(str_end - two_numbers, 2l); 114 115 const char *two_signs = "--10 999"; 116 errno = 0; 117 ASSERT_EQ(__llvm_libc::strtol(two_signs, &str_end, 10), 0l); 118 ASSERT_EQ(errno, 0); 119 EXPECT_EQ(str_end - two_signs, 1l); 120 121 const char *sign_before = "+2=4"; 122 errno = 0; 123 ASSERT_EQ(__llvm_libc::strtol(sign_before, &str_end, 10), 2l); 124 ASSERT_EQ(errno, 0); 125 EXPECT_EQ(str_end - sign_before, 2l); 126 127 const char *sign_after = "2+2=4"; 128 errno = 0; 129 ASSERT_EQ(__llvm_libc::strtol(sign_after, &str_end, 10), 2l); 130 ASSERT_EQ(errno, 0); 131 EXPECT_EQ(str_end - sign_after, 1l); 132 133 const char *tab_before = "\t10"; 134 errno = 0; 135 ASSERT_EQ(__llvm_libc::strtol(tab_before, &str_end, 10), 10l); 136 ASSERT_EQ(errno, 0); 137 EXPECT_EQ(str_end - tab_before, 3l); 138 139 const char *all_together = "\t -12345and+67890"; 140 errno = 0; 141 ASSERT_EQ(__llvm_libc::strtol(all_together, &str_end, 10), -12345l); 142 ASSERT_EQ(errno, 0); 143 EXPECT_EQ(str_end - all_together, 9l); 144 } 145 146 static char int_to_b36_char(int input) { 147 if (input < 0 || input > 36) 148 return '0'; 149 if (input < 10) 150 return '0' + input; 151 return 'A' + input - 10; 152 } 153 154 TEST(LlvmLibcStrToLTest, DecodeInOtherBases) { 155 char small_string[4] = {'\0', '\0', '\0', '\0'}; 156 for (unsigned int base = 2; base <= 36; ++base) { 157 for (long first_digit = 0; first_digit <= 36; ++first_digit) { 158 small_string[0] = int_to_b36_char(first_digit); 159 if (first_digit < base) { 160 errno = 0; 161 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 162 first_digit); 163 ASSERT_EQ(errno, 0); 164 } else { 165 errno = 0; 166 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 0l); 167 ASSERT_EQ(errno, 0); 168 } 169 } 170 } 171 172 for (unsigned int base = 2; base <= 36; ++base) { 173 for (long first_digit = 0; first_digit <= 36; ++first_digit) { 174 small_string[0] = int_to_b36_char(first_digit); 175 for (long second_digit = 0; second_digit <= 36; ++second_digit) { 176 small_string[1] = int_to_b36_char(second_digit); 177 if (first_digit < base && second_digit < base) { 178 errno = 0; 179 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 180 second_digit + (first_digit * base)); 181 ASSERT_EQ(errno, 0); 182 } else if (first_digit < base) { 183 errno = 0; 184 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 185 first_digit); 186 ASSERT_EQ(errno, 0); 187 } else { 188 errno = 0; 189 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 0l); 190 ASSERT_EQ(errno, 0); 191 } 192 } 193 } 194 } 195 196 for (unsigned int base = 2; base <= 36; ++base) { 197 for (long first_digit = 0; first_digit <= 36; ++first_digit) { 198 small_string[0] = int_to_b36_char(first_digit); 199 for (long second_digit = 0; second_digit <= 36; ++second_digit) { 200 small_string[1] = int_to_b36_char(second_digit); 201 for (long third_digit = 0; third_digit <= 36; ++third_digit) { 202 small_string[2] = int_to_b36_char(third_digit); 203 204 if (first_digit < base && second_digit < base && third_digit < base) { 205 errno = 0; 206 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 207 third_digit + (second_digit * base) + 208 (first_digit * base * base)); 209 ASSERT_EQ(errno, 0); 210 } else if (first_digit < base && second_digit < base) { 211 errno = 0; 212 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 213 second_digit + (first_digit * base)); 214 ASSERT_EQ(errno, 0); 215 } else if (first_digit < base) { 216 // if the base is 16 there is a special case for the prefix 0X. 217 // The number is treated as a one digit hexadecimal. 218 if (base == 16 && first_digit == 0 && second_digit == 33) { 219 if (third_digit < base) { 220 errno = 0; 221 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 222 third_digit); 223 ASSERT_EQ(errno, 0); 224 } else { 225 errno = 0; 226 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 0l); 227 ASSERT_EQ(errno, 0); 228 } 229 } else { 230 errno = 0; 231 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 232 first_digit); 233 ASSERT_EQ(errno, 0); 234 } 235 } else { 236 errno = 0; 237 ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 0l); 238 ASSERT_EQ(errno, 0); 239 } 240 } 241 } 242 } 243 } 244 } 245 246 TEST(LlvmLibcStrToLTest, CleanBaseSixteenDecode) { 247 char *str_end = nullptr; 248 249 const char *no_prefix = "123abc"; 250 errno = 0; 251 ASSERT_EQ(__llvm_libc::strtol(no_prefix, &str_end, 16), 0x123abcl); 252 ASSERT_EQ(errno, 0); 253 EXPECT_EQ(str_end - no_prefix, 6l); 254 255 const char *yes_prefix = "0x456def"; 256 errno = 0; 257 ASSERT_EQ(__llvm_libc::strtol(yes_prefix, &str_end, 16), 0x456defl); 258 ASSERT_EQ(errno, 0); 259 EXPECT_EQ(str_end - yes_prefix, 8l); 260 } 261 262 TEST(LlvmLibcStrToLTest, AutomaticBaseSelection) { 263 char *str_end = nullptr; 264 265 const char *base_ten = "12345"; 266 errno = 0; 267 ASSERT_EQ(__llvm_libc::strtol(base_ten, &str_end, 0), 12345l); 268 ASSERT_EQ(errno, 0); 269 EXPECT_EQ(str_end - base_ten, 5l); 270 271 const char *base_sixteen_no_prefix = "123abc"; 272 errno = 0; 273 ASSERT_EQ(__llvm_libc::strtol(base_sixteen_no_prefix, &str_end, 0), 123l); 274 ASSERT_EQ(errno, 0); 275 EXPECT_EQ(str_end - base_sixteen_no_prefix, 3l); 276 277 const char *base_sixteen_with_prefix = "0x456def"; 278 errno = 0; 279 ASSERT_EQ(__llvm_libc::strtol(base_sixteen_with_prefix, &str_end, 0), 280 0x456defl); 281 ASSERT_EQ(errno, 0); 282 EXPECT_EQ(str_end - base_sixteen_with_prefix, 8l); 283 284 const char *base_eight_with_prefix = "012345"; 285 errno = 0; 286 ASSERT_EQ(__llvm_libc::strtol(base_eight_with_prefix, &str_end, 0), 012345l); 287 ASSERT_EQ(errno, 0); 288 EXPECT_EQ(str_end - base_eight_with_prefix, 6l); 289 } 290