1 /*
2  * Copyright (c) 2022 LK Trusty Authors. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include <lk/compiler.h>
25 #include <stdlib.h>
26 
27 #include "gtest/gtest.h"
28 #include "printf_test_defs.h"
29 
30 class PrintfTest : public testing::TestWithParam<bool> {
31 };
32 
33 #define BUFFER_SIZE 100
TEST(PrintfTest,SmallIntegerPrintTest)34 TEST(PrintfTest, SmallIntegerPrintTest) {
35     char buffer[BUFFER_SIZE];
36 
37     snprintf_filtered(buffer, BUFFER_SIZE, "%d", 100);
38     EXPECT_STREQ(buffer, "100");
39 }
40 
TEST(PrintfTest,NullPointerPrintTest)41 TEST(PrintfTest, NullPointerPrintTest) {
42     char buffer[BUFFER_SIZE];
43 
44     snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %p", (void*)0);
45     EXPECT_STREQ(buffer, "pointer: 0x0");
46 }
47 
TEST(PrintfTest,SmallPointerPrintTest)48 TEST(PrintfTest, SmallPointerPrintTest) {
49     char buffer[BUFFER_SIZE];
50 
51     snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %p", (void*)0x1000);
52     EXPECT_STREQ(buffer, "pointer: 0x1000");
53 }
54 
TEST(PrintfTest,SmallPseudoNegativePointerPrintTest)55 TEST(PrintfTest, SmallPseudoNegativePointerPrintTest) {
56     char buffer[BUFFER_SIZE];
57 
58     snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %p", (void*)-4096);
59     EXPECT_STREQ(buffer, "pointer: 0xfffffffffffff000");
60 }
61 
62 
TEST(PrintfTest,PointerAndUnsignedOneLineOneBigOneSmall)63 TEST(PrintfTest, PointerAndUnsignedOneLineOneBigOneSmall) {
64     char buffer[BUFFER_SIZE];
65 
66     snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %p number: %u", 0x5000, 100);
67     EXPECT_STREQ_COND(buffer, "pointer1: 0x*** number: 100", "pointer1: 0x5000 number: 100", RELEASE_BUILD);
68 }
69 
TEST(PrintfTest,PointerAndUnsignedOneLineOneBigOneSmallInverse)70 TEST(PrintfTest, PointerAndUnsignedOneLineOneBigOneSmallInverse) {
71     char buffer[BUFFER_SIZE];
72 
73     snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %p number: %u", 0x500, 10000);
74     EXPECT_STREQ_COND(buffer, "pointer1: 0x500 number: ***", "pointer1: 0x500 number: 10000", RELEASE_BUILD);
75 }
76 
TEST(PrintfTest,OnePointersTwoIntsOneLineOneSmallTwoBig)77 TEST(PrintfTest, OnePointersTwoIntsOneLineOneSmallTwoBig) {
78     char buffer[BUFFER_SIZE];
79 
80     snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %p number: %u hex: %x", 0x5, 10000, 0X70);
81     EXPECT_STREQ_COND(buffer, "pointer1: 0x5 number: *** hex: 70", "pointer1: 0x5 number: 10000 hex: 70", RELEASE_BUILD);
82 }
83 
TEST(PrintfTest,OnePointersTwoIntsOneLineOneSmallTwoBigInverse)84 TEST(PrintfTest, OnePointersTwoIntsOneLineOneSmallTwoBigInverse) {
85     char buffer[BUFFER_SIZE];
86 
87     snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %p number: %u hex: %x", 0x5000, 10, 0X7000);
88     EXPECT_STREQ_COND(buffer, "pointer1: 0x*** number: 10 hex: ***", "pointer1: 0x5000 number: 10 hex: 7000", RELEASE_BUILD);
89 }
90 
TEST(PrintfTest,BiggerPseudoNegativePointerPrintTest)91 TEST(PrintfTest, BiggerPseudoNegativePointerPrintTest) {
92     char buffer[BUFFER_SIZE];
93 
94     snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %p", (void*)-4097);
95     EXPECT_STREQ_COND(buffer, "pointer: 0x***", "pointer: 0xffffffffffffefff", RELEASE_BUILD);
96 }
97 
TEST(PrintfTest,PointerAndUnsignedOneLine)98 TEST(PrintfTest, PointerAndUnsignedOneLine) {
99     char buffer[BUFFER_SIZE];
100 
101     snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %p number: %u", 0x5000, 10000);
102     EXPECT_STREQ_COND(buffer, "pointer1: 0x*** number: ***", "pointer1: 0x5000 number: 10000", RELEASE_BUILD);
103 }
104 
TEST(PrintfTest,SmallestPseudoNegativePointerPrintTest)105 TEST(PrintfTest, SmallestPseudoNegativePointerPrintTest) {
106     char buffer[BUFFER_SIZE];
107 
108     snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %p", (void*)-1);
109     EXPECT_STREQ(buffer, "pointer: 0xffffffffffffffff");
110 }
111 
TEST(PrintfTest,PointerPrintTest)112 TEST(PrintfTest, PointerPrintTest) {
113     char buffer[BUFFER_SIZE];
114 
115     snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %p", (void*)0x5000);
116     EXPECT_STREQ_COND(buffer, "pointer: 0x***", "pointer: 0x5000", RELEASE_BUILD);
117 }
118 
TEST(PrintfTest,PointerSprintfTest)119 TEST(PrintfTest, PointerSprintfTest) {
120     char buffer[BUFFER_SIZE];
121 
122     sprintf(buffer, "pointer: %p", (void*)0x5000);
123     EXPECT_STREQ(buffer, "pointer: 0x5000");
124 }
125 
TEST(PrintfTest,PointerSnprintfTest)126 TEST(PrintfTest, PointerSnprintfTest) {
127     char buffer[BUFFER_SIZE];
128 
129     snprintf(buffer, BUFFER_SIZE,"pointer: %p", (void*)0x5000);
130     EXPECT_STREQ(buffer, "pointer: 0x5000");
131 }
132 
TEST(PrintfTest,LargerIntTest)133 TEST(PrintfTest, LargerIntTest) {
134     char buffer[BUFFER_SIZE];
135 
136     snprintf_filtered(buffer, BUFFER_SIZE, "integer: %d", 4097);
137     EXPECT_STREQ_COND(buffer, "integer: ***", "integer: 4097", RELEASE_BUILD);
138 }
139 
TEST(PrintfTest,LargerNegIntTest)140 TEST(PrintfTest, LargerNegIntTest) {
141     char buffer[BUFFER_SIZE];
142 
143     snprintf_filtered(buffer, BUFFER_SIZE, "integer: %d", -4097);
144     EXPECT_STREQ_COND(buffer, "integer: ***", "integer: -4097", RELEASE_BUILD);
145 }
146 
TEST(PrintfTest,SmallIntTest)147 TEST(PrintfTest, SmallIntTest) {
148     char buffer[BUFFER_SIZE];
149 
150     snprintf_filtered(buffer, BUFFER_SIZE, "integer: %d", 4096);
151     EXPECT_STREQ(buffer, "integer: 4096");
152 }
153 
TEST(PrintfTest,SmallNegIntTest)154 TEST(PrintfTest, SmallNegIntTest) {
155     char buffer[BUFFER_SIZE];
156 
157     snprintf_filtered(buffer, BUFFER_SIZE, "integer: %d", -4096);
158     EXPECT_STREQ(buffer, "integer: -4096");
159 }
160 
TEST(PrintfTest,LargerUintTest)161 TEST(PrintfTest, LargerUintTest) {
162     char buffer[BUFFER_SIZE];
163 
164     snprintf_filtered(buffer, BUFFER_SIZE, "unsigned integer: %u", 4097);
165     EXPECT_STREQ_COND(buffer, "unsigned integer: ***", "unsigned integer: 4097", RELEASE_BUILD);
166 }
167 
TEST(PrintfTest,LargerHexTest)168 TEST(PrintfTest, LargerHexTest) {
169     char buffer[BUFFER_SIZE];
170 
171     snprintf_filtered(buffer, BUFFER_SIZE, "unsigned integer: 0x%x", 0x1001);
172     EXPECT_STREQ_COND(buffer, "unsigned integer: 0x***", "unsigned integer: 0x1001", RELEASE_BUILD);
173 }
174 
TEST(PrintfTest,PrintfBufferLargeEnough)175 TEST(PrintfTest, PrintfBufferLargeEnough) {
176     char buffer[BUFFER_SIZE];
177     memset(buffer, 0, BUFFER_SIZE);
178     buffer[5] = '@';
179 
180     snprintf_filtered(buffer, 5, "%x", 0x3000);
181     EXPECT_STREQ_COND(buffer, "***",
182                       "3000", RELEASE_BUILD);
183     EXPECT_EQ(buffer[5], '@');
184 }
185 
TEST(PrintfTest,PrintfBufferLargeEnoughForRelease)186 TEST(PrintfTest, PrintfBufferLargeEnoughForRelease) {
187     char buffer[BUFFER_SIZE];
188     memset(buffer, 0, BUFFER_SIZE);
189     buffer[4] = '@';
190 
191     snprintf_filtered(buffer, 4, "%x", 0x3000);
192     EXPECT_STREQ_COND(buffer, "***",
193                       "300", RELEASE_BUILD);
194     EXPECT_EQ(buffer[4], '@');
195 }
196 
TEST(PrintfTest,PrintfBufferTooSmallForRelease)197 TEST(PrintfTest, PrintfBufferTooSmallForRelease) {
198     char buffer[BUFFER_SIZE];
199     memset(buffer, 0, BUFFER_SIZE);
200     buffer[3] = '@';
201 
202     snprintf_filtered(buffer, 3, "%x", 0x3000);
203     EXPECT_STREQ_COND(buffer, "**",
204                       "30", RELEASE_BUILD);
205     EXPECT_EQ(buffer[3], '@');
206 }
207 
TEST(PrintfTest,SmallHexTest)208 TEST(PrintfTest, SmallHexTest) {
209     char buffer[BUFFER_SIZE];
210 
211     snprintf_filtered(buffer, BUFFER_SIZE, "unsigned integer: 0x%x", 0x1000);
212     EXPECT_STREQ(buffer, "unsigned integer: 0x1000");
213 }
214 
TEST(PrintfTest,PointerUnsignedOneLineFilterOne)215 TEST(PrintfTest, PointerUnsignedOneLineFilterOne) {
216     char buffer[BUFFER_SIZE];
217 
218     snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %px number: %u", 0x5000, 10000);
219     EXPECT_STREQ_COND(buffer, "pointer1: 0x5000 number: ***", "pointer1: 0x5000 number: 10000", RELEASE_BUILD);
220 }
221 
TEST(PrintfTest,PointerUnsignedOneLineFilterOneInverse)222 TEST(PrintfTest, PointerUnsignedOneLineFilterOneInverse) {
223     char buffer[BUFFER_SIZE];
224 
225     snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %p number: %ux", 0x5000, 10000);
226     EXPECT_STREQ_COND(buffer, "pointer1: 0x*** number: 10000", "pointer1: 0x5000 number: 10000", RELEASE_BUILD);
227 }
228 
TEST(PrintfTest,PointerUnsignedHexOneLineFilterOne)229 TEST(PrintfTest, PointerUnsignedHexOneLineFilterOne) {
230     char buffer[BUFFER_SIZE];
231 
232     snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %px number: %u hex: %xx", 0x5000, 10000, 0X7000);
233     EXPECT_STREQ_COND(buffer, "pointer1: 0x5000 number: *** hex: 7000", "pointer1: 0x5000 number: 10000 hex: 7000", RELEASE_BUILD);
234 }
235 
TEST(PrintfTest,PointerUnsignedHexOneLineFilterOneInverse)236 TEST(PrintfTest, PointerUnsignedHexOneLineFilterOneInverse) {
237     char buffer[BUFFER_SIZE];
238 
239     snprintf_filtered(buffer, BUFFER_SIZE, "pointer1: %p number: %ux hex: %x", 0x5000, 10000, 0X7000);
240     EXPECT_STREQ_COND(buffer, "pointer1: 0x*** number: 10000 hex: ***", "pointer1: 0x5000 number: 10000 hex: 7000", RELEASE_BUILD);
241 }
242 
TEST(PrintfTest,ReleaseUnfilteredPointerPrintTest)243 TEST(PrintfTest, ReleaseUnfilteredPointerPrintTest) {
244     char buffer[BUFFER_SIZE];
245 
246     snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %px", (void*)0x5000);
247     EXPECT_STREQ(buffer, "pointer: 0x5000");
248 }
249 
TEST(PrintfTest,ReleaseUnfilteredLargNegIntTest)250 TEST(PrintfTest, ReleaseUnfilteredLargNegIntTest) {
251     char buffer[BUFFER_SIZE];
252 
253     snprintf_filtered(buffer, BUFFER_SIZE, "integer: %dx", -4097);
254     EXPECT_STREQ(buffer, "integer: -4097");
255 }
256 
TEST(PrintfTest,ReleaseUnfilteredLargerHexTest)257 TEST(PrintfTest, ReleaseUnfilteredLargerHexTest) {
258     char buffer[BUFFER_SIZE];
259 
260     snprintf_filtered(buffer, BUFFER_SIZE, "unsigned integer: 0x%xx", 0x1001);
261     EXPECT_STREQ(buffer, "unsigned integer: 0x1001");
262 }
263 
TEST(PrintfTest,ReleaseUnfilteredLargerUintTest)264 TEST(PrintfTest, ReleaseUnfilteredLargerUintTest) {
265     char buffer[BUFFER_SIZE];
266 
267     snprintf_filtered(buffer, BUFFER_SIZE, "unsigned integer: %ux", 4097);
268     EXPECT_STREQ(buffer, "unsigned integer: 4097");
269 }
270 
TEST(PrintfTest,ReleaseUnfilteredLargerUintXAtEndTest)271 TEST(PrintfTest, ReleaseUnfilteredLargerUintXAtEndTest) {
272     char buffer[BUFFER_SIZE];
273 
274     snprintf_filtered(buffer, BUFFER_SIZE, "unsigned integer: %uxx", 34127);
275     EXPECT_STREQ(buffer, "unsigned integer: 34127x");
276 }
277 
TEST(PrintfTest,ReleaseUnfilteredPrintfBufferLargeEnoughTest)278 TEST(PrintfTest, ReleaseUnfilteredPrintfBufferLargeEnoughTest) {
279     char buffer[BUFFER_SIZE];
280     memset(buffer, 0, BUFFER_SIZE);
281     buffer[5] = '@';
282 
283     snprintf_filtered(buffer, 5, "%xx", 0x3000);
284     EXPECT_STREQ(buffer, "3000");
285     EXPECT_EQ(buffer[5], '@');
286 }
287 
TEST(PrintfTest,ReleaseUnfilteredPrintfBufferLargeEnoughForReleaseTest)288 TEST(PrintfTest, ReleaseUnfilteredPrintfBufferLargeEnoughForReleaseTest) {
289     char buffer[BUFFER_SIZE];
290     memset(buffer, 0, BUFFER_SIZE);
291     buffer[4] = '@';
292 
293     snprintf_filtered(buffer, 4, "%xx", 0x3000);
294     EXPECT_STREQ(buffer,"300");
295     EXPECT_EQ(buffer[4], '@');
296 }
297 
TEST(PrintfTest,ReleaseUnfilteredPrintfBufferTooSmallForReleaseTest)298 TEST(PrintfTest, ReleaseUnfilteredPrintfBufferTooSmallForReleaseTest) {
299     char buffer[BUFFER_SIZE];
300     memset(buffer, 0, BUFFER_SIZE);
301     buffer[3] = '@';
302 
303     snprintf_filtered(buffer, 3, "%xx", 0x3000);
304     EXPECT_STREQ(buffer, "30");
305     EXPECT_EQ(buffer[3], '@');
306 }
307 
TEST(PrintfTest,ReleaseUnfilteredPrintfStringXPrintsTest)308 TEST(PrintfTest, ReleaseUnfilteredPrintfStringXPrintsTest) {
309     char buffer[BUFFER_SIZE];
310 
311     snprintf_filtered(buffer, BUFFER_SIZE, "%sx", "hello");
312     EXPECT_STREQ(buffer, "hellox");
313 }
314 
TEST(PrintfTest,ThreeModifierTogetherOneNotFilteredTest)315 TEST(PrintfTest, ThreeModifierTogetherOneNotFilteredTest) {
316     char buffer[BUFFER_SIZE];
317 
318     snprintf_filtered(buffer, BUFFER_SIZE, "%d%xx%u", 98765, 0x43210, 123456);
319     EXPECT_STREQ_COND(buffer, "***43210***", "9876543210123456", RELEASE_BUILD);
320 }
321 
TEST(PrintfTest,ThreeModifierTogetherOneNotFilteredInverseTest)322 TEST(PrintfTest, ThreeModifierTogetherOneNotFilteredInverseTest) {
323     char buffer[BUFFER_SIZE];
324 
325     snprintf_filtered(buffer, BUFFER_SIZE, "%dx%x%ux", 98765, 0x43210, 123456);
326     EXPECT_STREQ_COND(buffer, "98765***123456", "9876543210123456", RELEASE_BUILD);
327 }
328 
TEST(PrintfTest,ReleaseUnfilteredThreeModifiersTest)329 TEST(PrintfTest, ReleaseUnfilteredThreeModifiersTest) {
330     char buffer[BUFFER_SIZE];
331 
332     snprintf_filtered(buffer, BUFFER_SIZE, "pointer: %px unsigned: %ux signed: %dx", (void*)0x5000, 7000, 80000);
333     EXPECT_STREQ(buffer, "pointer: 0x5000 unsigned: 7000 signed: 80000");
334 }
335 
TEST(PrintfTest,SnprintfModifierNotUsedTest)336 TEST(PrintfTest, SnprintfModifierNotUsedTest) {
337     char buffer[BUFFER_SIZE];
338 
339     snprintf(buffer, BUFFER_SIZE, "hex: %xx pointer: %px unsigned: %ux signed: %dx", 2, (void*) 3, 4, 5);
340 
341     EXPECT_STREQ(buffer, "hex: 2x pointer: 0x3x unsigned: 4x signed: 5x");
342 }
343