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