xref: /aosp_15_r20/external/llvm-libc/test/src/stdio/sscanf_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===-- Unittests for sscanf ----------------------------------------------===//
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/stdio/sscanf.h"
10 
11 #include "hdr/stdio_macros.h" // For EOF
12 #include "src/__support/CPP/limits.h"
13 #include "src/__support/FPUtil/FPBits.h"
14 #include "test/UnitTest/FPMatcher.h"
15 #include "test/UnitTest/Test.h"
16 
TEST(LlvmLibcSScanfTest,SimpleStringConv)17 TEST(LlvmLibcSScanfTest, SimpleStringConv) {
18   int ret_val;
19   char buffer[10];
20   char buffer2[10];
21   ret_val = LIBC_NAMESPACE::sscanf("abc123", "abc %s", buffer);
22   ASSERT_EQ(ret_val, 1);
23   ASSERT_STREQ(buffer, "123");
24 
25   ret_val = LIBC_NAMESPACE::sscanf("abc123", "%3s %3s", buffer, buffer2);
26   ASSERT_EQ(ret_val, 2);
27   ASSERT_STREQ(buffer, "abc");
28   ASSERT_STREQ(buffer2, "123");
29 
30   ret_val = LIBC_NAMESPACE::sscanf("abc 123", "%3s%3s", buffer, buffer2);
31   ASSERT_EQ(ret_val, 2);
32   ASSERT_STREQ(buffer, "abc");
33   ASSERT_STREQ(buffer2, "123");
34 }
35 
TEST(LlvmLibcSScanfTest,IntConvSimple)36 TEST(LlvmLibcSScanfTest, IntConvSimple) {
37   int ret_val;
38   int result = 0;
39   ret_val = LIBC_NAMESPACE::sscanf("123", "%d", &result);
40   EXPECT_EQ(ret_val, 1);
41   EXPECT_EQ(result, 123);
42 
43   ret_val = LIBC_NAMESPACE::sscanf("456", "%i", &result);
44   EXPECT_EQ(ret_val, 1);
45   EXPECT_EQ(result, 456);
46 
47   ret_val = LIBC_NAMESPACE::sscanf("789", "%x", &result);
48   EXPECT_EQ(ret_val, 1);
49   EXPECT_EQ(result, 0x789);
50 
51   ret_val = LIBC_NAMESPACE::sscanf("012", "%o", &result);
52   EXPECT_EQ(ret_val, 1);
53   EXPECT_EQ(result, 012);
54 
55   ret_val = LIBC_NAMESPACE::sscanf("345", "%u", &result);
56   EXPECT_EQ(ret_val, 1);
57   EXPECT_EQ(result, 345);
58 
59   // 288 characters
60   ret_val = LIBC_NAMESPACE::sscanf("10000000000000000000000000000000"
61                                    "00000000000000000000000000000000"
62                                    "00000000000000000000000000000000"
63                                    "00000000000000000000000000000000"
64                                    "00000000000000000000000000000000"
65                                    "00000000000000000000000000000000"
66                                    "00000000000000000000000000000000"
67                                    "00000000000000000000000000000000"
68                                    "00000000000000000000000000000000",
69                                    "%d", &result);
70   EXPECT_EQ(ret_val, 1);
71   EXPECT_EQ(result, int(LIBC_NAMESPACE::cpp::numeric_limits<intmax_t>::max()));
72 
73   ret_val = LIBC_NAMESPACE::sscanf("Not an integer", "%d", &result);
74   EXPECT_EQ(ret_val, 0);
75 }
76 
TEST(LlvmLibcSScanfTest,IntConvLengthModifier)77 TEST(LlvmLibcSScanfTest, IntConvLengthModifier) {
78   int ret_val;
79   uintmax_t max_result = 0;
80   int int_result = 0;
81   char char_result = 0;
82 
83   ret_val = LIBC_NAMESPACE::sscanf("123", "%ju", &max_result);
84   EXPECT_EQ(ret_val, 1);
85   EXPECT_EQ(max_result, uintmax_t(123));
86 
87   // Check overflow handling
88   ret_val = LIBC_NAMESPACE::sscanf("999999999999999999999999999999999999",
89                                    "%ju", &max_result);
90   EXPECT_EQ(ret_val, 1);
91   EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
92 
93   // Because this is unsigned, any out of range value should return the maximum,
94   // even with a negative sign.
95   ret_val = LIBC_NAMESPACE::sscanf("-999999999999999999999999999999999999",
96                                    "%ju", &max_result);
97   EXPECT_EQ(ret_val, 1);
98   EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
99 
100   ret_val = LIBC_NAMESPACE::sscanf("-18446744073709551616", "%ju", &max_result);
101   EXPECT_EQ(ret_val, 1);
102   EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
103 
104   // But any number below the maximum should have the - sign applied.
105   ret_val = LIBC_NAMESPACE::sscanf("-1", "%ju", &max_result);
106   EXPECT_EQ(ret_val, 1);
107   EXPECT_EQ(max_result, uintmax_t(-1));
108 
109   ret_val = LIBC_NAMESPACE::sscanf("-1", "%u", &int_result);
110   EXPECT_EQ(ret_val, 1);
111   EXPECT_EQ(int_result, -1);
112 
113   max_result = 0xff00ff00ff00ff00;
114   char_result = 0x6f;
115 
116   // Overflows for sizes larger than the maximum are handled by casting.
117   ret_val = LIBC_NAMESPACE::sscanf("8589967360", "%d", &int_result);
118   EXPECT_EQ(ret_val, 1);
119   EXPECT_EQ(int_result, int(8589967360)); // 2^33 + 2^15
120 
121   // Check that the adjacent values weren't touched by the overflow.
122   ASSERT_EQ(max_result, uintmax_t(0xff00ff00ff00ff00));
123   ASSERT_EQ(char_result, char(0x6f));
124 
125   ret_val = LIBC_NAMESPACE::sscanf("-8589967360", "%d", &int_result);
126   EXPECT_EQ(ret_val, 1);
127   EXPECT_EQ(int_result, int(-8589967360));
128   ASSERT_EQ(max_result, uintmax_t(0xff00ff00ff00ff00));
129   ASSERT_EQ(char_result, char(0x6f));
130 
131   ret_val = LIBC_NAMESPACE::sscanf("25", "%hhd", &char_result);
132   EXPECT_EQ(ret_val, 1);
133   EXPECT_EQ(char_result, char(25));
134 }
135 
TEST(LlvmLibcSScanfTest,IntConvBaseSelection)136 TEST(LlvmLibcSScanfTest, IntConvBaseSelection) {
137   int ret_val;
138   int result = 0;
139   ret_val = LIBC_NAMESPACE::sscanf("0xabc123", "%i", &result);
140   EXPECT_EQ(ret_val, 1);
141   EXPECT_EQ(result, 0xabc123);
142 
143   ret_val = LIBC_NAMESPACE::sscanf("0456", "%i", &result);
144   EXPECT_EQ(ret_val, 1);
145   EXPECT_EQ(result, 0456);
146 
147   ret_val = LIBC_NAMESPACE::sscanf("0999", "%i", &result);
148   EXPECT_EQ(ret_val, 1);
149   EXPECT_EQ(result, 0);
150 
151   ret_val = LIBC_NAMESPACE::sscanf("123abc456", "%i", &result);
152   EXPECT_EQ(ret_val, 1);
153   EXPECT_EQ(result, 123);
154 }
155 
TEST(LlvmLibcSScanfTest,IntConvMaxLengthTests)156 TEST(LlvmLibcSScanfTest, IntConvMaxLengthTests) {
157   int ret_val;
158   int result = 0;
159 
160   ret_val = LIBC_NAMESPACE::sscanf("12", "%1d", &result);
161   EXPECT_EQ(ret_val, 1);
162   EXPECT_EQ(result, 1);
163 
164   ret_val = LIBC_NAMESPACE::sscanf("-1", "%1d", &result);
165   EXPECT_EQ(ret_val, 0);
166   EXPECT_EQ(result, 0);
167 
168   ret_val = LIBC_NAMESPACE::sscanf("+1", "%1d", &result);
169   EXPECT_EQ(ret_val, 0);
170   EXPECT_EQ(result, 0);
171 
172   ret_val = LIBC_NAMESPACE::sscanf("01", "%1d", &result);
173   EXPECT_EQ(ret_val, 1);
174   EXPECT_EQ(result, 0);
175 
176   ret_val = LIBC_NAMESPACE::sscanf("01", "%1i", &result);
177   EXPECT_EQ(ret_val, 1);
178   EXPECT_EQ(result, 0);
179 
180   result = -999;
181 
182   // 0x is a valid prefix, but not a valid number. This should be a matching
183   // failure and should not modify the values.
184   ret_val = LIBC_NAMESPACE::sscanf("0x1", "%2i", &result);
185   EXPECT_EQ(ret_val, 0);
186   EXPECT_EQ(result, -999);
187 
188   ret_val = LIBC_NAMESPACE::sscanf("-0x1", "%3i", &result);
189   EXPECT_EQ(ret_val, 0);
190   EXPECT_EQ(result, -999);
191 
192   ret_val = LIBC_NAMESPACE::sscanf("0x1", "%3i", &result);
193   EXPECT_EQ(ret_val, 1);
194   EXPECT_EQ(result, 1);
195 
196   ret_val = LIBC_NAMESPACE::sscanf("-0x1", "%4i", &result);
197   EXPECT_EQ(ret_val, 1);
198   EXPECT_EQ(result, -1);
199 
200   ret_val = LIBC_NAMESPACE::sscanf("-0x123", "%4i", &result);
201   EXPECT_EQ(ret_val, 1);
202   EXPECT_EQ(result, -1);
203 
204   ret_val = LIBC_NAMESPACE::sscanf("123456789", "%5i", &result);
205   EXPECT_EQ(ret_val, 1);
206   EXPECT_EQ(result, 12345);
207 
208   ret_val = LIBC_NAMESPACE::sscanf("123456789", "%10i", &result);
209   EXPECT_EQ(ret_val, 1);
210   EXPECT_EQ(result, 123456789);
211 }
212 
TEST(LlvmLibcSScanfTest,IntConvNoWriteTests)213 TEST(LlvmLibcSScanfTest, IntConvNoWriteTests) {
214   int ret_val;
215   // Result shouldn't be used by these tests, but it's safer to have it and
216   // check it.
217   int result = 0;
218   ret_val = LIBC_NAMESPACE::sscanf("-1", "%*1d", &result);
219   EXPECT_EQ(ret_val, 0);
220   EXPECT_EQ(result, 0);
221 
222   ret_val = LIBC_NAMESPACE::sscanf("01", "%*1i", &result);
223   EXPECT_EQ(ret_val, 1);
224   EXPECT_EQ(result, 0);
225 
226   ret_val = LIBC_NAMESPACE::sscanf("0x1", "%*2i", &result);
227   EXPECT_EQ(ret_val, 0);
228   EXPECT_EQ(result, 0);
229 
230   ret_val = LIBC_NAMESPACE::sscanf("a", "%*i", &result);
231   EXPECT_EQ(ret_val, 0);
232   EXPECT_EQ(result, 0);
233 
234   ret_val = LIBC_NAMESPACE::sscanf("123", "%*i", &result);
235   EXPECT_EQ(ret_val, 1);
236   EXPECT_EQ(result, 0);
237 }
238 
239 #ifndef LIBC_COPT_SCANF_DISABLE_FLOAT
TEST(LlvmLibcSScanfTest,FloatConvSimple)240 TEST(LlvmLibcSScanfTest, FloatConvSimple) {
241   int ret_val;
242   float result = 0;
243 
244   float inf = LIBC_NAMESPACE::fputil::FPBits<float>::inf().get_val();
245   float nan = LIBC_NAMESPACE::fputil::FPBits<float>::quiet_nan().get_val();
246 
247   ret_val = LIBC_NAMESPACE::sscanf("123", "%f", &result);
248   EXPECT_EQ(ret_val, 1);
249   EXPECT_FP_EQ(result, 123.0);
250 
251   ret_val = LIBC_NAMESPACE::sscanf("456.1", "%a", &result);
252   EXPECT_EQ(ret_val, 1);
253   EXPECT_FP_EQ(result, 456.1);
254 
255   ret_val = LIBC_NAMESPACE::sscanf("0x789.ap0", "%e", &result);
256   EXPECT_EQ(ret_val, 1);
257   EXPECT_FP_EQ(result, 0x789.ap0);
258 
259   ret_val = LIBC_NAMESPACE::sscanf("0x.8", "%e", &result);
260   EXPECT_EQ(ret_val, 1);
261   EXPECT_FP_EQ(result, 0x0.8p0);
262 
263   ret_val = LIBC_NAMESPACE::sscanf("0x8.", "%e", &result);
264   EXPECT_EQ(ret_val, 1);
265   EXPECT_FP_EQ(result, 0x8.0p0);
266 
267   ret_val = LIBC_NAMESPACE::sscanf("+12.0e1", "%g", &result);
268   EXPECT_EQ(ret_val, 1);
269   EXPECT_FP_EQ(result, 12.0e1);
270 
271   ret_val = LIBC_NAMESPACE::sscanf("inf", "%F", &result);
272   EXPECT_EQ(ret_val, 1);
273   EXPECT_FP_EQ(result, inf);
274 
275   ret_val = LIBC_NAMESPACE::sscanf("NaN", "%A", &result);
276   EXPECT_EQ(ret_val, 1);
277   EXPECT_FP_EQ(result, nan);
278 
279   ret_val = LIBC_NAMESPACE::sscanf("-InFiNiTy", "%E", &result);
280   EXPECT_EQ(ret_val, 1);
281   EXPECT_FP_EQ(result, -inf);
282 
283   ret_val = LIBC_NAMESPACE::sscanf("1e10", "%G", &result);
284   EXPECT_EQ(ret_val, 1);
285   EXPECT_FP_EQ(result, 1e10);
286 
287   ret_val = LIBC_NAMESPACE::sscanf(".1", "%G", &result);
288   EXPECT_EQ(ret_val, 1);
289   EXPECT_FP_EQ(result, 0.1);
290 
291   ret_val = LIBC_NAMESPACE::sscanf("1.", "%G", &result);
292   EXPECT_EQ(ret_val, 1);
293   EXPECT_FP_EQ(result, 1.0);
294 
295   ret_val = LIBC_NAMESPACE::sscanf("0", "%f", &result);
296   EXPECT_EQ(ret_val, 1);
297   EXPECT_FP_EQ(result, 0.0);
298 
299   ret_val = LIBC_NAMESPACE::sscanf("Not a float", "%f", &result);
300   EXPECT_EQ(ret_val, 0);
301 }
302 
TEST(LlvmLibcSScanfTest,FloatConvLengthModifier)303 TEST(LlvmLibcSScanfTest, FloatConvLengthModifier) {
304   int ret_val;
305   double d_result = 0;
306   long double ld_result = 0;
307 
308   double d_inf = LIBC_NAMESPACE::fputil::FPBits<double>::inf().get_val();
309   long double ld_nan =
310       LIBC_NAMESPACE::fputil::FPBits<long double>::quiet_nan().get_val();
311 
312   ret_val = LIBC_NAMESPACE::sscanf("123", "%lf", &d_result);
313   EXPECT_EQ(ret_val, 1);
314   EXPECT_FP_EQ(d_result, 123.0);
315 
316   ret_val = LIBC_NAMESPACE::sscanf("456.1", "%La", &ld_result);
317   EXPECT_EQ(ret_val, 1);
318   EXPECT_FP_EQ(ld_result, 456.1L);
319 
320   ret_val = LIBC_NAMESPACE::sscanf("inf", "%le", &d_result);
321   EXPECT_EQ(ret_val, 1);
322   EXPECT_FP_EQ(d_result, d_inf);
323 
324   ret_val = LIBC_NAMESPACE::sscanf("nan", "%Lg", &ld_result);
325   EXPECT_EQ(ret_val, 1);
326   EXPECT_FP_EQ(ld_result, ld_nan);
327 
328   ret_val = LIBC_NAMESPACE::sscanf("1e-300", "%lF", &d_result);
329   EXPECT_EQ(ret_val, 1);
330   EXPECT_FP_EQ(d_result, 1e-300);
331 
332   ret_val = LIBC_NAMESPACE::sscanf("1.0e600", "%LA", &ld_result);
333   EXPECT_EQ(ret_val, 1);
334 // 1e600 may be larger than the maximum long double (if long double is double).
335 // In that case both of these should be evaluated as inf.
336 #ifdef LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64
337   EXPECT_FP_EQ(ld_result, d_inf);
338 #else
339   EXPECT_FP_EQ(ld_result, 1.0e600L);
340 #endif
341 }
342 
TEST(LlvmLibcSScanfTest,FloatConvLongNumber)343 TEST(LlvmLibcSScanfTest, FloatConvLongNumber) {
344   int ret_val;
345   float result = 0;
346   double d_result = 0;
347 
348   // 32 characters
349   ret_val =
350       LIBC_NAMESPACE::sscanf("123456789012345678901234567890.0", "%f", &result);
351   EXPECT_EQ(ret_val, 1);
352   EXPECT_FP_EQ(result, 123456789012345678901234567890.0f);
353 
354   // 64 characters
355   ret_val = LIBC_NAMESPACE::sscanf(
356       "123456789012345678901234567890123456789012345678901234567890.000", "%la",
357       &d_result);
358   EXPECT_EQ(ret_val, 1);
359   EXPECT_FP_EQ(
360       d_result,
361       123456789012345678901234567890123456789012345678901234567890.000);
362 
363   // 128 characters
364   ret_val = LIBC_NAMESPACE::sscanf(
365       "123456789012345678901234567890123456789012345678901234567890"
366       "123456789012345678901234567890123456789012345678901234567890.0000000",
367       "%le", &d_result);
368   EXPECT_EQ(ret_val, 1);
369   EXPECT_FP_EQ(
370       d_result,
371       123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.0000000);
372 
373   // 256 characters
374   ret_val = LIBC_NAMESPACE::sscanf("10000000000000000000000000000000"
375                                    "00000000000000000000000000000000"
376                                    "00000000000000000000000000000000"
377                                    "00000000000000000000000000000000"
378                                    "00000000000000000000000000000000"
379                                    "00000000000000000000000000000000"
380                                    "00000000000000000000000000000000"
381                                    "00000000000000000000000000000000",
382                                    "%lf", &d_result);
383   EXPECT_EQ(ret_val, 1);
384   EXPECT_FP_EQ(d_result, 1e255);
385 
386   // 288 characters
387   ret_val = LIBC_NAMESPACE::sscanf("10000000000000000000000000000000"
388                                    "00000000000000000000000000000000"
389                                    "00000000000000000000000000000000"
390                                    "00000000000000000000000000000000"
391                                    "00000000000000000000000000000000"
392                                    "00000000000000000000000000000000"
393                                    "00000000000000000000000000000000"
394                                    "00000000000000000000000000000000"
395                                    "00000000000000000000000000000000",
396                                    "%lf", &d_result);
397   EXPECT_EQ(ret_val, 1);
398   EXPECT_FP_EQ(d_result, 1e287);
399 }
400 
TEST(LlvmLibcSScanfTest,FloatConvComplexParsing)401 TEST(LlvmLibcSScanfTest, FloatConvComplexParsing) {
402   int ret_val;
403   float result = 0;
404 
405   float inf = LIBC_NAMESPACE::fputil::FPBits<float>::inf().get_val();
406   float nan = LIBC_NAMESPACE::fputil::FPBits<float>::quiet_nan().get_val();
407 
408   ret_val = LIBC_NAMESPACE::sscanf("0x1.0e3", "%f", &result);
409   EXPECT_EQ(ret_val, 1);
410   EXPECT_FP_EQ(result, 0x1.0e3p0);
411 
412   ret_val = LIBC_NAMESPACE::sscanf("", "%a", &result);
413   EXPECT_EQ(ret_val, 0);
414 
415   ret_val = LIBC_NAMESPACE::sscanf("+", "%a", &result);
416   EXPECT_EQ(ret_val, 0);
417 
418   ret_val = LIBC_NAMESPACE::sscanf("-", "%a", &result);
419   EXPECT_EQ(ret_val, 0);
420 
421   ret_val = LIBC_NAMESPACE::sscanf("+.", "%a", &result);
422   EXPECT_EQ(ret_val, 0);
423 
424   ret_val = LIBC_NAMESPACE::sscanf("-.e+10", "%a", &result);
425   EXPECT_EQ(ret_val, 0);
426 
427   // This is a specific example from the standard. Its behavior diverges from
428   // other implementations that accept "100e" as being the same as "100e0"
429   ret_val = LIBC_NAMESPACE::sscanf("100er", "%a", &result);
430   EXPECT_EQ(ret_val, 0);
431 
432   ret_val = LIBC_NAMESPACE::sscanf("nah", "%a", &result);
433   EXPECT_EQ(ret_val, 0);
434 
435   ret_val = LIBC_NAMESPACE::sscanf("indirection", "%a", &result);
436   EXPECT_EQ(ret_val, 0);
437 
438   ret_val = LIBC_NAMESPACE::sscanf("infnan", "%a", &result);
439   EXPECT_EQ(ret_val, 1);
440   EXPECT_FP_EQ(result, inf);
441 
442   ret_val = LIBC_NAMESPACE::sscanf("naninf", "%a", &result);
443   EXPECT_EQ(ret_val, 1);
444   EXPECT_FP_EQ(result, nan);
445 
446   ret_val = LIBC_NAMESPACE::sscanf("infinityinfinity", "%a", &result);
447   EXPECT_EQ(ret_val, 1);
448   EXPECT_FP_EQ(result, inf);
449 
450   // For %f to accept a string as representing it has to be either "inf" or
451   // "infinity" when it stops. It only stops when it encounters a character that
452   // isn't the next one in the string, so it accepts "infi" as the the longest
453   // prefix of a possibly valid floating-point number, but determines that it is
454   // not valid and returns a matching failure. This is because it can only unget
455   // one character so when it finds that the character after the second 'i' is
456   // not the next character in "infinity" it can't rewind to the point where it
457   // had just "inf".
458   ret_val = LIBC_NAMESPACE::sscanf("infi", "%a", &result);
459   EXPECT_EQ(ret_val, 0);
460 
461   ret_val = LIBC_NAMESPACE::sscanf("infinite", "%a", &result);
462   EXPECT_EQ(ret_val, 0);
463 
464   ret_val = LIBC_NAMESPACE::sscanf("-.1e1", "%f", &result);
465   EXPECT_EQ(ret_val, 1);
466   EXPECT_FP_EQ(result, -.1e1);
467 
468   ret_val = LIBC_NAMESPACE::sscanf("1.2.e1", "%f", &result);
469   EXPECT_EQ(ret_val, 1);
470   EXPECT_FP_EQ(result, 1.2);
471 }
472 
TEST(LlvmLibcSScanfTest,FloatConvMaxWidth)473 TEST(LlvmLibcSScanfTest, FloatConvMaxWidth) {
474   int ret_val;
475   float result = 0;
476 
477   float inf = LIBC_NAMESPACE::fputil::FPBits<float>::inf().get_val();
478 
479   ret_val = LIBC_NAMESPACE::sscanf("123", "%3f", &result);
480   EXPECT_EQ(ret_val, 1);
481   EXPECT_FP_EQ(result, 123.0);
482 
483   ret_val = LIBC_NAMESPACE::sscanf("123", "%5f", &result);
484   EXPECT_EQ(ret_val, 1);
485   EXPECT_FP_EQ(result, 123.0);
486 
487   ret_val = LIBC_NAMESPACE::sscanf("456", "%1f", &result);
488   EXPECT_EQ(ret_val, 1);
489   EXPECT_FP_EQ(result, 4.0);
490 
491   ret_val = LIBC_NAMESPACE::sscanf("-789", "%1f", &result);
492   EXPECT_EQ(ret_val, 0);
493 
494   ret_val = LIBC_NAMESPACE::sscanf("-123", "%2f", &result);
495   EXPECT_EQ(ret_val, 1);
496   EXPECT_FP_EQ(result, -1.0);
497 
498   ret_val = LIBC_NAMESPACE::sscanf("inf", "%2f", &result);
499   EXPECT_EQ(ret_val, 0);
500 
501   ret_val = LIBC_NAMESPACE::sscanf("nan", "%1f", &result);
502   EXPECT_EQ(ret_val, 0);
503 
504   ret_val = LIBC_NAMESPACE::sscanf("-inf", "%3f", &result);
505   EXPECT_EQ(ret_val, 0);
506 
507   ret_val = LIBC_NAMESPACE::sscanf("-nan", "%3f", &result);
508   EXPECT_EQ(ret_val, 0);
509 
510   // If the max length were not here this would fail as discussed above, but
511   // since the max length limits it to the 3 it succeeds.
512   ret_val = LIBC_NAMESPACE::sscanf("infinite", "%3f", &result);
513   EXPECT_EQ(ret_val, 1);
514   EXPECT_FP_EQ(result, inf);
515 
516   ret_val = LIBC_NAMESPACE::sscanf("-infinite", "%4f", &result);
517   EXPECT_EQ(ret_val, 1);
518   EXPECT_FP_EQ(result, -inf);
519 
520   ret_val = LIBC_NAMESPACE::sscanf("01", "%1f", &result);
521   EXPECT_EQ(ret_val, 1);
522   EXPECT_FP_EQ(result, 0.0);
523 
524   ret_val = LIBC_NAMESPACE::sscanf("0x1", "%2f", &result);
525   EXPECT_EQ(ret_val, 1);
526   EXPECT_FP_EQ(result, 0.0);
527 
528   ret_val = LIBC_NAMESPACE::sscanf("100e", "%4f", &result);
529   EXPECT_EQ(ret_val, 0);
530 
531   ret_val = LIBC_NAMESPACE::sscanf("100e+10", "%5f", &result);
532   EXPECT_EQ(ret_val, 0);
533 
534   ret_val = LIBC_NAMESPACE::sscanf("100e10", "%5f", &result);
535   EXPECT_EQ(ret_val, 1);
536   EXPECT_FP_EQ(result, 100e1);
537 }
538 
TEST(LlvmLibcSScanfTest,FloatConvNoWrite)539 TEST(LlvmLibcSScanfTest, FloatConvNoWrite) {
540   int ret_val;
541   float result = 0;
542 
543   ret_val = LIBC_NAMESPACE::sscanf("123", "%*f", &result);
544   EXPECT_EQ(ret_val, 1);
545   EXPECT_FP_EQ(result, 0.0);
546 
547   ret_val = LIBC_NAMESPACE::sscanf("456.1", "%*a", &result);
548   EXPECT_EQ(ret_val, 1);
549   EXPECT_FP_EQ(result, 0.0);
550 
551   ret_val = LIBC_NAMESPACE::sscanf("0x789.ap0", "%*e", &result);
552   EXPECT_EQ(ret_val, 1);
553   EXPECT_FP_EQ(result, 0.0);
554 
555   ret_val = LIBC_NAMESPACE::sscanf("+12.0e1", "%*g", &result);
556   EXPECT_EQ(ret_val, 1);
557   EXPECT_FP_EQ(result, 0.0);
558 
559   ret_val = LIBC_NAMESPACE::sscanf("inf", "%*F", &result);
560   EXPECT_EQ(ret_val, 1);
561   EXPECT_FP_EQ(result, 0.0);
562 
563   ret_val = LIBC_NAMESPACE::sscanf("NaN", "%*A", &result);
564   EXPECT_EQ(ret_val, 1);
565   EXPECT_FP_EQ(result, 0.0);
566 
567   ret_val = LIBC_NAMESPACE::sscanf("-InFiNiTy", "%*E", &result);
568   EXPECT_EQ(ret_val, 1);
569   EXPECT_FP_EQ(result, 0.0);
570 
571   ret_val = LIBC_NAMESPACE::sscanf("1e10", "%*G", &result);
572   EXPECT_EQ(ret_val, 1);
573   EXPECT_FP_EQ(result, 0.0);
574 
575   ret_val = LIBC_NAMESPACE::sscanf(".1", "%*G", &result);
576   EXPECT_EQ(ret_val, 1);
577   EXPECT_FP_EQ(result, 0.0);
578 
579   ret_val = LIBC_NAMESPACE::sscanf("123", "%*3f", &result);
580   EXPECT_EQ(ret_val, 1);
581   EXPECT_FP_EQ(result, 0.0);
582 
583   ret_val = LIBC_NAMESPACE::sscanf("123", "%*5f", &result);
584   EXPECT_EQ(ret_val, 1);
585   EXPECT_FP_EQ(result, 0.0);
586 
587   ret_val = LIBC_NAMESPACE::sscanf("456", "%*1f", &result);
588   EXPECT_EQ(ret_val, 1);
589   EXPECT_FP_EQ(result, 0.0);
590 
591   ret_val = LIBC_NAMESPACE::sscanf("Not a float", "%*f", &result);
592   EXPECT_EQ(ret_val, 0);
593 }
594 #endif
595 
596 #ifndef LIBC_COPT_SCANF_DISABLE_INDEX_MODE
TEST(LlvmLibcSScanfTest,CurPosCombined)597 TEST(LlvmLibcSScanfTest, CurPosCombined) {
598   int ret_val;
599   int result = -1;
600   char c_result = 0;
601 
602   ret_val = LIBC_NAMESPACE::sscanf("some text", "%n", &result);
603   // %n doesn't count as a conversion for the return value.
604   EXPECT_EQ(ret_val, 0);
605   EXPECT_EQ(result, 0);
606 
607   ret_val = LIBC_NAMESPACE::sscanf("1234567890", "12345%n", &result);
608   EXPECT_EQ(ret_val, 0);
609   EXPECT_EQ(result, 5);
610 
611   ret_val = LIBC_NAMESPACE::sscanf("1234567890", "12345%n", &result);
612   EXPECT_EQ(ret_val, 0);
613   EXPECT_EQ(result, 5);
614 
615   // 288 characters
616   ret_val = LIBC_NAMESPACE::sscanf("10000000000000000000000000000000"
617                                    "00000000000000000000000000000000"
618                                    "00000000000000000000000000000000"
619                                    "00000000000000000000000000000000"
620                                    "00000000000000000000000000000000"
621                                    "00000000000000000000000000000000"
622                                    "00000000000000000000000000000000"
623                                    "00000000000000000000000000000000"
624                                    "00000000000000000000000000000000",
625                                    "%*d%hhn", &c_result);
626   EXPECT_EQ(ret_val, 1);
627   EXPECT_EQ(c_result, char(288)); // Overflow is handled by casting.
628 
629   // 320 characters
630   ret_val = LIBC_NAMESPACE::sscanf("10000000000000000000000000000000"
631                                    "00000000000000000000000000000000"
632                                    "00000000000000000000000000000000"
633                                    "00000000000000000000000000000000"
634                                    "00000000000000000000000000000000"
635                                    "00000000000000000000000000000000"
636                                    "00000000000000000000000000000000"
637                                    "00000000000000000000000000000000"
638                                    "00000000000000000000000000000000"
639                                    "00000000000000000000000000000000",
640                                    "%*d%n", &result);
641   EXPECT_EQ(ret_val, 1);
642   EXPECT_EQ(result, 320);
643 }
644 #endif
645 
TEST(LlvmLibcSScanfTest,PointerConvCombined)646 TEST(LlvmLibcSScanfTest, PointerConvCombined) {
647   int ret_val;
648   void *result;
649 
650   ret_val = LIBC_NAMESPACE::sscanf("(nullptr)", "%p", &result);
651   EXPECT_EQ(ret_val, 1);
652   EXPECT_EQ(result, static_cast<void *>(nullptr));
653 
654   ret_val = LIBC_NAMESPACE::sscanf("(NuLlPtR)", "%p", &result);
655   EXPECT_EQ(ret_val, 1);
656   EXPECT_EQ(result, static_cast<void *>(nullptr));
657 
658   ret_val = LIBC_NAMESPACE::sscanf("(NULLPTR)", "%p", &result);
659   EXPECT_EQ(ret_val, 1);
660   EXPECT_EQ(result, static_cast<void *>(nullptr));
661 
662   ret_val = LIBC_NAMESPACE::sscanf("(null)", "%p", &result);
663   EXPECT_EQ(ret_val, 0);
664 
665   ret_val = LIBC_NAMESPACE::sscanf("(nullptr2", "%p", &result);
666   EXPECT_EQ(ret_val, 0);
667 
668   ret_val = LIBC_NAMESPACE::sscanf("0", "%p", &result);
669   EXPECT_EQ(ret_val, 1);
670   EXPECT_EQ(result, reinterpret_cast<void *>(0));
671 
672   ret_val = LIBC_NAMESPACE::sscanf("100", "%p", &result);
673   EXPECT_EQ(ret_val, 1);
674   EXPECT_EQ(result, reinterpret_cast<void *>(0x100));
675 
676   ret_val = LIBC_NAMESPACE::sscanf("-1", "%p", &result);
677   EXPECT_EQ(ret_val, 1);
678   EXPECT_EQ(result, reinterpret_cast<void *>(-1));
679 
680   ret_val = LIBC_NAMESPACE::sscanf("0xabcDEFG", "%p", &result);
681   EXPECT_EQ(ret_val, 1);
682   EXPECT_EQ(result, reinterpret_cast<void *>(0xabcdef));
683 }
684 
TEST(LlvmLibcSScanfTest,CombinedConv)685 TEST(LlvmLibcSScanfTest, CombinedConv) {
686   int ret_val;
687   int result = 0;
688   char buffer[10];
689   ret_val = LIBC_NAMESPACE::sscanf("123abc", "%i%s", &result, buffer);
690   EXPECT_EQ(ret_val, 2);
691   EXPECT_EQ(result, 123);
692   ASSERT_STREQ(buffer, "abc");
693 
694   result = -1;
695 
696   // 0x is a valid prefix, but not a valid number. This should be a matching
697   // failure and should not modify the values.
698   ret_val = LIBC_NAMESPACE::sscanf("0xZZZ", "%i%s", &result, buffer);
699   EXPECT_EQ(ret_val, 0);
700   EXPECT_EQ(result, -1);
701   ASSERT_STREQ(buffer, "abc");
702 
703   ret_val = LIBC_NAMESPACE::sscanf("0xZZZ", "%X%s", &result, buffer);
704   EXPECT_EQ(ret_val, 0);
705   EXPECT_EQ(result, -1);
706   ASSERT_STREQ(buffer, "abc");
707 }
708