]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Test/UnitTest/Library/BaseLib/Base64UnitTest.c
MdePkg/UnitTestBaseLib: Add check for pointer BinData
[mirror_edk2.git] / MdePkg / Test / UnitTest / Library / BaseLib / Base64UnitTest.c
CommitLineData
e50c2bb3
MK
1/** @file\r
2 Unit tests of Base64 conversion APIs in BaseLib.\r
3\r
4 Copyright (C) Microsoft Corporation.\r
5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include <Uefi.h>\r
10#include <Library/BaseLib.h>\r
11#include <Library/BaseMemoryLib.h>\r
12#include <Library/DebugLib.h>\r
13#include <Library/MemoryAllocationLib.h>\r
14#include <Library/UnitTestLib.h>\r
15\r
16#define UNIT_TEST_APP_NAME "BaseLib Unit Test Application"\r
17#define UNIT_TEST_APP_VERSION "1.0"\r
18\r
19/**\r
20 RFC 4648 https://tools.ietf.org/html/rfc4648 test vectors\r
21\r
22 BASE64("") = ""\r
23 BASE64("f") = "Zg=="\r
24 BASE64("fo") = "Zm8="\r
25 BASE64("foo") = "Zm9v"\r
26 BASE64("foob") = "Zm9vYg=="\r
27 BASE64("fooba") = "Zm9vYmE="\r
28 BASE64("foobar") = "Zm9vYmFy"\r
29\r
30 The test vectors are using ascii strings for the binary data\r
31 */\r
32\r
33typedef struct {\r
34 CHAR8 *TestInput;\r
35 CHAR8 *TestOutput;\r
36 EFI_STATUS ExpectedStatus;\r
37 VOID *BufferToFree;\r
38 UINTN ExpectedSize;\r
39} BASIC_TEST_CONTEXT;\r
40\r
41#define B64_TEST_1 ""\r
42#define BIN_TEST_1 ""\r
43\r
44#define B64_TEST_2 "Zg=="\r
45#define BIN_TEST_2 "f"\r
46\r
47#define B64_TEST_3 "Zm8="\r
48#define BIN_TEST_3 "fo"\r
49\r
50#define B64_TEST_4 "Zm9v"\r
51#define BIN_TEST_4 "foo"\r
52\r
53#define B64_TEST_5 "Zm9vYg=="\r
54#define BIN_TEST_5 "foob"\r
55\r
56#define B64_TEST_6 "Zm9vYmE="\r
57#define BIN_TEST_6 "fooba"\r
58\r
59#define B64_TEST_7 "Zm9vYmFy"\r
60#define BIN_TEST_7 "foobar"\r
61\r
62// Adds all white space - also ends the last quantum with only spaces afterwards\r
63#define B64_TEST_8_IN " \t\v Zm9\r\nvYmFy \f "\r
64#define BIN_TEST_8 "foobar"\r
65\r
66// Not a quantum multiple of 4\r
67#define B64_ERROR_1 "Zm9vymFy="\r
68\r
69// Invalid characters in the string\r
70#define B64_ERROR_2 "Zm$vymFy"\r
71\r
72// Too many '=' characters\r
73#define B64_ERROR_3 "Z==="\r
74\r
75// Poorly placed '='\r
76#define B64_ERROR_4 "Zm=vYmFy"\r
77\r
78#define MAX_TEST_STRING_SIZE (200)\r
79\r
80// ------------------------------------------------ Input----------Output-----------Result-------Free--Expected Output Size\r
81static BASIC_TEST_CONTEXT mBasicEncodeTest1 = {BIN_TEST_1, B64_TEST_1, EFI_SUCCESS, NULL, sizeof(B64_TEST_1)};\r
82static BASIC_TEST_CONTEXT mBasicEncodeTest2 = {BIN_TEST_2, B64_TEST_2, EFI_SUCCESS, NULL, sizeof(B64_TEST_2)};\r
83static BASIC_TEST_CONTEXT mBasicEncodeTest3 = {BIN_TEST_3, B64_TEST_3, EFI_SUCCESS, NULL, sizeof(B64_TEST_3)};\r
84static BASIC_TEST_CONTEXT mBasicEncodeTest4 = {BIN_TEST_4, B64_TEST_4, EFI_SUCCESS, NULL, sizeof(B64_TEST_4)};\r
85static BASIC_TEST_CONTEXT mBasicEncodeTest5 = {BIN_TEST_5, B64_TEST_5, EFI_SUCCESS, NULL, sizeof(B64_TEST_5)};\r
86static BASIC_TEST_CONTEXT mBasicEncodeTest6 = {BIN_TEST_6, B64_TEST_6, EFI_SUCCESS, NULL, sizeof(B64_TEST_6)};\r
87static BASIC_TEST_CONTEXT mBasicEncodeTest7 = {BIN_TEST_7, B64_TEST_7, EFI_SUCCESS, NULL, sizeof(B64_TEST_7)};\r
88static BASIC_TEST_CONTEXT mBasicEncodeError1 = {BIN_TEST_7, B64_TEST_1, EFI_BUFFER_TOO_SMALL, NULL, sizeof(B64_TEST_7)};\r
89\r
90static BASIC_TEST_CONTEXT mBasicDecodeTest1 = {B64_TEST_1, BIN_TEST_1, EFI_SUCCESS, NULL, sizeof(BIN_TEST_1)-1};\r
91static BASIC_TEST_CONTEXT mBasicDecodeTest2 = {B64_TEST_2, BIN_TEST_2, EFI_SUCCESS, NULL, sizeof(BIN_TEST_2)-1};\r
92static BASIC_TEST_CONTEXT mBasicDecodeTest3 = {B64_TEST_3, BIN_TEST_3, EFI_SUCCESS, NULL, sizeof(BIN_TEST_3)-1};\r
93static BASIC_TEST_CONTEXT mBasicDecodeTest4 = {B64_TEST_4, BIN_TEST_4, EFI_SUCCESS, NULL, sizeof(BIN_TEST_4)-1};\r
94static BASIC_TEST_CONTEXT mBasicDecodeTest5 = {B64_TEST_5, BIN_TEST_5, EFI_SUCCESS, NULL, sizeof(BIN_TEST_5)-1};\r
95static BASIC_TEST_CONTEXT mBasicDecodeTest6 = {B64_TEST_6, BIN_TEST_6, EFI_SUCCESS, NULL, sizeof(BIN_TEST_6)-1};\r
96static BASIC_TEST_CONTEXT mBasicDecodeTest7 = {B64_TEST_7, BIN_TEST_7, EFI_SUCCESS, NULL, sizeof(BIN_TEST_7)-1};\r
97static BASIC_TEST_CONTEXT mBasicDecodeTest8 = {B64_TEST_8_IN, BIN_TEST_8, EFI_SUCCESS, NULL, sizeof(BIN_TEST_8)-1};\r
98\r
99static BASIC_TEST_CONTEXT mBasicDecodeError1 = {B64_ERROR_1, B64_ERROR_1, EFI_INVALID_PARAMETER, NULL, 0};\r
100static BASIC_TEST_CONTEXT mBasicDecodeError2 = {B64_ERROR_2, B64_ERROR_2, EFI_INVALID_PARAMETER, NULL, 0};\r
101static BASIC_TEST_CONTEXT mBasicDecodeError3 = {B64_ERROR_3, B64_ERROR_3, EFI_INVALID_PARAMETER, NULL, 0};\r
102static BASIC_TEST_CONTEXT mBasicDecodeError4 = {B64_ERROR_4, B64_ERROR_4, EFI_INVALID_PARAMETER, NULL, 0};\r
103static BASIC_TEST_CONTEXT mBasicDecodeError5 = {B64_TEST_7, BIN_TEST_1, EFI_BUFFER_TOO_SMALL, NULL, sizeof(BIN_TEST_7)-1};\r
104\r
105/**\r
106 Simple clean up method to make sure tests clean up even if interrupted and fail\r
107 in the middle.\r
108**/\r
109STATIC\r
110VOID\r
111EFIAPI\r
112CleanUpB64TestContext (\r
113 IN UNIT_TEST_CONTEXT Context\r
114 )\r
115{\r
116 BASIC_TEST_CONTEXT *Btc;\r
117\r
118 Btc = (BASIC_TEST_CONTEXT *)Context;\r
119 if (Btc != NULL) {\r
120 //free string if set\r
121 if (Btc->BufferToFree != NULL) {\r
122 FreePool (Btc->BufferToFree);\r
123 Btc->BufferToFree = NULL;\r
124 }\r
125 }\r
126}\r
127\r
128/**\r
129 Unit test for Base64 encode APIs of BaseLib.\r
130\r
131 @param[in] Context [Optional] An optional parameter that enables:\r
132 1) test-case reuse with varied parameters and\r
133 2) test-case re-entry for Target tests that need a\r
134 reboot. This parameter is a VOID* and it is the\r
135 responsibility of the test author to ensure that the\r
136 contents are well understood by all test cases that may\r
137 consume it.\r
138\r
139 @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
140 case was successful.\r
141 @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
142**/\r
143STATIC\r
144UNIT_TEST_STATUS\r
145EFIAPI\r
146RfcEncodeTest (\r
147 IN UNIT_TEST_CONTEXT Context\r
148 )\r
149{\r
150 BASIC_TEST_CONTEXT *Btc;\r
151 CHAR8 *b64String;\r
152 CHAR8 *binString;\r
153 UINTN b64StringSize;\r
154 EFI_STATUS Status;\r
155 UINT8 *BinData;\r
156 UINTN BinSize;\r
157 CHAR8 *b64WorkString;\r
158 UINTN ReturnSize;\r
159 INTN CompareStatus;\r
160 UINTN indx;\r
161\r
162 Btc = (BASIC_TEST_CONTEXT *) Context;\r
163 binString = Btc->TestInput;\r
164 b64String = Btc->TestOutput;\r
165\r
166 //\r
167 // Only testing the the translate functionality, so preallocate the proper\r
168 // string buffer.\r
169 //\r
170\r
171 b64StringSize = AsciiStrnSizeS(b64String, MAX_TEST_STRING_SIZE);\r
172 BinSize = AsciiStrnLenS(binString, MAX_TEST_STRING_SIZE);\r
173 BinData = (UINT8 *) binString;\r
174\r
175 b64WorkString = (CHAR8 *) AllocatePool(b64StringSize);\r
176 UT_ASSERT_NOT_NULL(b64WorkString);\r
177\r
178 Btc->BufferToFree = b64WorkString;\r
179 ReturnSize = b64StringSize;\r
180\r
181 Status = Base64Encode(BinData, BinSize, b64WorkString, &ReturnSize);\r
182\r
183 UT_ASSERT_STATUS_EQUAL(Status, Btc->ExpectedStatus);\r
184\r
185 UT_ASSERT_EQUAL(ReturnSize, Btc->ExpectedSize);\r
186\r
187 if (!EFI_ERROR (Btc->ExpectedStatus)) {\r
188 if (ReturnSize != 0) {\r
189 CompareStatus = AsciiStrnCmp (b64String, b64WorkString, ReturnSize);\r
190 if (CompareStatus != 0) {\r
191 UT_LOG_ERROR ("b64 string compare error - size=%d\n", ReturnSize);\r
192 for (indx = 0; indx < ReturnSize; indx++) {\r
193 UT_LOG_ERROR (" %2.2x", 0xff & b64String[indx]);\r
194 }\r
195 UT_LOG_ERROR ("\n b64 work string:\n");\r
196 for (indx = 0; indx < ReturnSize; indx++) {\r
197 UT_LOG_ERROR (" %2.2x", 0xff & b64WorkString[indx]);\r
198 }\r
199 UT_LOG_ERROR ("\n");\r
200 }\r
201 UT_ASSERT_EQUAL (CompareStatus, 0);\r
202 }\r
203 }\r
204\r
205 Btc->BufferToFree = NULL;\r
206 FreePool (b64WorkString);\r
207 return UNIT_TEST_PASSED;\r
208}\r
209\r
210/**\r
211 Unit test for Base64 decode APIs of BaseLib.\r
212\r
213 @param[in] Context [Optional] An optional parameter that enables:\r
214 1) test-case reuse with varied parameters and\r
215 2) test-case re-entry for Target tests that need a\r
216 reboot. This parameter is a VOID* and it is the\r
217 responsibility of the test author to ensure that the\r
218 contents are well understood by all test cases that may\r
219 consume it.\r
220\r
221 @retval UNIT_TEST_PASSED The Unit test has completed and the test\r
222 case was successful.\r
223 @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.\r
224**/\r
225STATIC\r
226UNIT_TEST_STATUS\r
227EFIAPI\r
228RfcDecodeTest(\r
229 IN UNIT_TEST_CONTEXT Context\r
230 )\r
231{\r
232 BASIC_TEST_CONTEXT *Btc;\r
233 CHAR8 *b64String;\r
234 CHAR8 *binString;\r
235 EFI_STATUS Status;\r
236 UINTN b64StringLen;\r
237 UINTN ReturnSize;\r
238 UINT8 *BinData;\r
239 UINTN BinSize;\r
240 INTN CompareStatus;\r
241 UINTN indx;\r
242\r
243 Btc = (BASIC_TEST_CONTEXT *)Context;\r
244 b64String = Btc->TestInput;\r
245 binString = Btc->TestOutput;\r
246\r
247 //\r
248 // Only testing the the translate functionality\r
249 //\r
250\r
251 b64StringLen = AsciiStrnLenS (b64String, MAX_TEST_STRING_SIZE);\r
252 BinSize = AsciiStrnLenS (binString, MAX_TEST_STRING_SIZE);\r
253\r
254 BinData = AllocatePool (BinSize);\r
090e267b 255 UT_ASSERT_NOT_NULL(BinData);\r
e50c2bb3 256\r
090e267b 257 Btc->BufferToFree = BinData;\r
e50c2bb3 258 ReturnSize = BinSize;\r
090e267b 259\r
e50c2bb3
MK
260 Status = Base64Decode (b64String, b64StringLen, BinData, &ReturnSize);\r
261\r
262 UT_ASSERT_STATUS_EQUAL (Status, Btc->ExpectedStatus);\r
263\r
264 // If an error is not expected, check the results\r
265 if (EFI_ERROR (Btc->ExpectedStatus)) {\r
266 if (Btc->ExpectedStatus == EFI_BUFFER_TOO_SMALL) {\r
267 UT_ASSERT_EQUAL (ReturnSize, Btc->ExpectedSize);\r
268 }\r
269 } else {\r
270 UT_ASSERT_EQUAL (ReturnSize, Btc->ExpectedSize);\r
271 if (ReturnSize != 0) {\r
272 CompareStatus = CompareMem (binString, BinData, ReturnSize);\r
273 if (CompareStatus != 0) {\r
274 UT_LOG_ERROR ("bin string compare error - size=%d\n", ReturnSize);\r
275 for (indx = 0; indx < ReturnSize; indx++) {\r
276 UT_LOG_ERROR (" %2.2x", 0xff & binString[indx]);\r
277 }\r
278 UT_LOG_ERROR ("\nBinData:\n");\r
279 for (indx = 0; indx < ReturnSize; indx++) {\r
280 UT_LOG_ERROR (" %2.2x", 0xff & BinData[indx]);\r
281 }\r
282 UT_LOG_ERROR ("\n");\r
283 }\r
284 UT_ASSERT_EQUAL (CompareStatus, 0);\r
285 }\r
286 }\r
287\r
288 Btc->BufferToFree = NULL;\r
289 FreePool (BinData);\r
290 return UNIT_TEST_PASSED;\r
291}\r
292\r
293/**\r
294 Initialze the unit test framework, suite, and unit tests for the\r
295 Base64 conversion APIs of BaseLib and run the unit tests.\r
296\r
297 @retval EFI_SUCCESS All test cases were dispatched.\r
298 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to\r
299 initialize the unit tests.\r
300**/\r
301STATIC\r
302EFI_STATUS\r
303EFIAPI\r
304UnitTestingEntry (\r
305 VOID\r
306 )\r
307{\r
308 EFI_STATUS Status;\r
309 UNIT_TEST_FRAMEWORK_HANDLE Fw;\r
310 UNIT_TEST_SUITE_HANDLE b64EncodeTests;\r
311 UNIT_TEST_SUITE_HANDLE b64DecodeTests;\r
312\r
313 Fw = NULL;\r
314\r
315 DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));\r
316\r
317 //\r
318 // Start setting up the test framework for running the tests.\r
319 //\r
320 Status = InitUnitTestFramework (&Fw, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION);\r
321 if (EFI_ERROR (Status)) {\r
322 DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));\r
323 goto EXIT;\r
324 }\r
325\r
326 //\r
327 // Populate the B64 Encode Unit Test Suite.\r
328 //\r
329 Status = CreateUnitTestSuite (&b64EncodeTests, Fw, "b64 Encode binary to Ascii string", "BaseLib.b64Encode", NULL, NULL);\r
330 if (EFI_ERROR (Status)) {\r
331 DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for b64EncodeTests\n"));\r
332 Status = EFI_OUT_OF_RESOURCES;\r
333 goto EXIT;\r
334 }\r
335\r
336 // --------------Suite-----------Description--------------Class Name----------Function--------Pre---Post-------------------Context-----------\r
337 AddTestCase (b64EncodeTests, "RFC 4686 Test Vector - Empty", "Test1", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeTest1);\r
338 AddTestCase (b64EncodeTests, "RFC 4686 Test Vector - f", "Test2", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeTest2);\r
339 AddTestCase (b64EncodeTests, "RFC 4686 Test Vector - fo", "Test3", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeTest3);\r
340 AddTestCase (b64EncodeTests, "RFC 4686 Test Vector - foo", "Test4", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeTest4);\r
341 AddTestCase (b64EncodeTests, "RFC 4686 Test Vector - foob", "Test5", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeTest5);\r
342 AddTestCase (b64EncodeTests, "RFC 4686 Test Vector - fooba", "Test6", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeTest6);\r
343 AddTestCase (b64EncodeTests, "RFC 4686 Test Vector - foobar", "Test7", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeTest7);\r
344 AddTestCase (b64EncodeTests, "Too small of output buffer", "Error1", RfcEncodeTest, NULL, CleanUpB64TestContext, &mBasicEncodeError1);\r
345 //\r
346 // Populate the B64 Decode Unit Test Suite.\r
347 //\r
348 Status = CreateUnitTestSuite (&b64DecodeTests, Fw, "b64 Decode Ascii string to binary", "BaseLib.b64Decode", NULL, NULL);\r
349 if (EFI_ERROR (Status)) {\r
350 DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for b64Decode Tests\n"));\r
351 Status = EFI_OUT_OF_RESOURCES;\r
352 goto EXIT;\r
353 }\r
354\r
355 AddTestCase (b64DecodeTests, "RFC 4686 Test Vector - Empty", "Test1", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest1);\r
356 AddTestCase (b64DecodeTests, "RFC 4686 Test Vector - f", "Test2", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest2);\r
357 AddTestCase (b64DecodeTests, "RFC 4686 Test Vector - fo", "Test3", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest3);\r
358 AddTestCase (b64DecodeTests, "RFC 4686 Test Vector - foo", "Test4", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest4);\r
359 AddTestCase (b64DecodeTests, "RFC 4686 Test Vector - foob", "Test5", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest5);\r
360 AddTestCase (b64DecodeTests, "RFC 4686 Test Vector - fooba", "Test6", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest6);\r
361 AddTestCase (b64DecodeTests, "RFC 4686 Test Vector - foobar", "Test7", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest7);\r
362 AddTestCase (b64DecodeTests, "Ignore Whitespace test", "Test8", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeTest8);\r
363\r
364 AddTestCase (b64DecodeTests, "Not a quantum multiple of 4", "Error1", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeError1);\r
365 AddTestCase (b64DecodeTests, "Invalid characters in the string", "Error2", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeError2);\r
366 AddTestCase (b64DecodeTests, "Too many padding characters", "Error3", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeError3);\r
367 AddTestCase (b64DecodeTests, "Incorrectly placed padding character", "Error4", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeError4);\r
368 AddTestCase (b64DecodeTests, "Too small of output buffer", "Error5", RfcDecodeTest, NULL, CleanUpB64TestContext, &mBasicDecodeError5);\r
369\r
370 //\r
371 // Execute the tests.\r
372 //\r
373 Status = RunAllTestSuites (Fw);\r
374\r
375EXIT:\r
376 if (Fw) {\r
377 FreeUnitTestFramework (Fw);\r
378 }\r
379\r
380 return Status;\r
381}\r
382\r
383/**\r
384 Standard UEFI entry point for target based unit test execution from UEFI Shell.\r
385**/\r
386EFI_STATUS\r
387EFIAPI\r
388BaseLibUnitTestAppEntry (\r
389 IN EFI_HANDLE ImageHandle,\r
390 IN EFI_SYSTEM_TABLE *SystemTable\r
391 )\r
392{\r
393 return UnitTestingEntry ();\r
394}\r
395\r
396/**\r
397 Standard POSIX C entry point for host based unit test execution.\r
398**/\r
399int\r
400main (\r
401 int argc,\r
402 char *argv[]\r
403 )\r
404{\r
405 return UnitTestingEntry ();\r
406}\r