xref: /aosp_15_r20/external/llvm-libc/test/src/stdio/vsscanf_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/vsscanf.h"
10 
11 #include "test/UnitTest/Test.h"
12 
call_vsscanf(const char * __restrict buffer,const char * __restrict format,...)13 int call_vsscanf(const char *__restrict buffer, const char *__restrict format,
14                  ...) {
15   va_list vlist;
16   va_start(vlist, format);
17   int ret = LIBC_NAMESPACE::vsscanf(buffer, format, vlist);
18   va_end(vlist);
19   return ret;
20 }
21 
TEST(LlvmLibcVSScanfTest,SimpleStringConv)22 TEST(LlvmLibcVSScanfTest, SimpleStringConv) {
23   int ret_val;
24   char buffer[10];
25   char buffer2[10];
26   ret_val = call_vsscanf("abc123", "abc %s", buffer);
27   ASSERT_EQ(ret_val, 1);
28   ASSERT_STREQ(buffer, "123");
29 
30   ret_val = call_vsscanf("abc123", "%3s %3s", buffer, buffer2);
31   ASSERT_EQ(ret_val, 2);
32   ASSERT_STREQ(buffer, "abc");
33   ASSERT_STREQ(buffer2, "123");
34 
35   ret_val = call_vsscanf("abc 123", "%3s%3s", buffer, buffer2);
36   ASSERT_EQ(ret_val, 2);
37   ASSERT_STREQ(buffer, "abc");
38   ASSERT_STREQ(buffer2, "123");
39 }
40 
TEST(LlvmLibcVSScanfTest,IntConvSimple)41 TEST(LlvmLibcVSScanfTest, IntConvSimple) {
42   int ret_val;
43   int result = 0;
44   ret_val = call_vsscanf("123", "%d", &result);
45   EXPECT_EQ(ret_val, 1);
46   EXPECT_EQ(result, 123);
47 
48   ret_val = call_vsscanf("456", "%i", &result);
49   EXPECT_EQ(ret_val, 1);
50   EXPECT_EQ(result, 456);
51 
52   ret_val = call_vsscanf("789", "%x", &result);
53   EXPECT_EQ(ret_val, 1);
54   EXPECT_EQ(result, 0x789);
55 
56   ret_val = call_vsscanf("012", "%o", &result);
57   EXPECT_EQ(ret_val, 1);
58   EXPECT_EQ(result, 012);
59 
60   ret_val = call_vsscanf("345", "%u", &result);
61   EXPECT_EQ(ret_val, 1);
62   EXPECT_EQ(result, 345);
63 
64   // 288 characters
65   ret_val = call_vsscanf("10000000000000000000000000000000"
66                          "00000000000000000000000000000000"
67                          "00000000000000000000000000000000"
68                          "00000000000000000000000000000000"
69                          "00000000000000000000000000000000"
70                          "00000000000000000000000000000000"
71                          "00000000000000000000000000000000"
72                          "00000000000000000000000000000000"
73                          "00000000000000000000000000000000",
74                          "%d", &result);
75   EXPECT_EQ(ret_val, 1);
76   EXPECT_EQ(result, int(LIBC_NAMESPACE::cpp::numeric_limits<intmax_t>::max()));
77 
78   ret_val = call_vsscanf("Not an integer", "%d", &result);
79   EXPECT_EQ(ret_val, 0);
80 }
81 
TEST(LlvmLibcVSScanfTest,IntConvLengthModifier)82 TEST(LlvmLibcVSScanfTest, IntConvLengthModifier) {
83   int ret_val;
84   uintmax_t max_result = 0;
85   int int_result = 0;
86   char char_result = 0;
87 
88   ret_val = call_vsscanf("123", "%ju", &max_result);
89   EXPECT_EQ(ret_val, 1);
90   EXPECT_EQ(max_result, uintmax_t(123));
91 
92   // Check overflow handling
93   ret_val =
94       call_vsscanf("999999999999999999999999999999999999", "%ju", &max_result);
95   EXPECT_EQ(ret_val, 1);
96   EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
97 
98   // Because this is unsigned, any out of range value should return the maximum,
99   // even with a negative sign.
100   ret_val =
101       call_vsscanf("-999999999999999999999999999999999999", "%ju", &max_result);
102   EXPECT_EQ(ret_val, 1);
103   EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
104 
105   ret_val = call_vsscanf("-18446744073709551616", "%ju", &max_result);
106   EXPECT_EQ(ret_val, 1);
107   EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
108 
109   // But any number below the maximum should have the - sign applied.
110   ret_val = call_vsscanf("-1", "%ju", &max_result);
111   EXPECT_EQ(ret_val, 1);
112   EXPECT_EQ(max_result, uintmax_t(-1));
113 
114   ret_val = call_vsscanf("-1", "%u", &int_result);
115   EXPECT_EQ(ret_val, 1);
116   EXPECT_EQ(int_result, -1);
117 
118   max_result = 0xff00ff00ff00ff00;
119   char_result = 0x6f;
120 
121   // Overflows for sizes larger than the maximum are handled by casting.
122   ret_val = call_vsscanf("8589967360", "%d", &int_result);
123   EXPECT_EQ(ret_val, 1);
124   EXPECT_EQ(int_result, int(8589967360)); // 2^33 + 2^15
125 
126   // Check that the adjacent values weren't touched by the overflow.
127   ASSERT_EQ(max_result, uintmax_t(0xff00ff00ff00ff00));
128   ASSERT_EQ(char_result, char(0x6f));
129 
130   ret_val = call_vsscanf("-8589967360", "%d", &int_result);
131   EXPECT_EQ(ret_val, 1);
132   EXPECT_EQ(int_result, int(-8589967360));
133   ASSERT_EQ(max_result, uintmax_t(0xff00ff00ff00ff00));
134   ASSERT_EQ(char_result, char(0x6f));
135 
136   ret_val = call_vsscanf("25", "%hhd", &char_result);
137   EXPECT_EQ(ret_val, 1);
138   EXPECT_EQ(char_result, char(25));
139 }
140 
TEST(LlvmLibcVSScanfTest,IntConvBaseSelection)141 TEST(LlvmLibcVSScanfTest, IntConvBaseSelection) {
142   int ret_val;
143   int result = 0;
144   ret_val = call_vsscanf("0xabc123", "%i", &result);
145   EXPECT_EQ(ret_val, 1);
146   EXPECT_EQ(result, 0xabc123);
147 
148   ret_val = call_vsscanf("0456", "%i", &result);
149   EXPECT_EQ(ret_val, 1);
150   EXPECT_EQ(result, 0456);
151 
152   ret_val = call_vsscanf("0999", "%i", &result);
153   EXPECT_EQ(ret_val, 1);
154   EXPECT_EQ(result, 0);
155 
156   ret_val = call_vsscanf("123abc456", "%i", &result);
157   EXPECT_EQ(ret_val, 1);
158   EXPECT_EQ(result, 123);
159 }
160