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
TEST(LlvmLibcStrToLLTest,InvalidBase)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
TEST(LlvmLibcStrToLLTest,CleanBaseTenDecode)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
TEST(LlvmLibcStrToLLTest,MessyBaseTenDecode)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
int_to_b36_char(int input)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
TEST(LlvmLibcStrToLLTest,DecodeInOtherBases)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
TEST(LlvmLibcStrToLLTest,CleanBaseSixteenDecode)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
TEST(LlvmLibcStrToLLTest,MessyBaseSixteenDecode)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
TEST(LlvmLibcStrToLLTest,AutomaticBaseSelection)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