// ---------------------------------------------------------------------------- // Unit test for the string helper functions // ---------------------------------------------------------------------------- #include "precompiled_unittests_core.h" #include "core/StringHelpers.h" namespace ITF { namespace { struct Base64TestData { const u8 m_data [16]; size_t m_dataSize; const char* m_base64String; }; const Base64TestData g_base64Tests [] = { { {}, 0, "" }, { {199}, 1, "xw==" }, { {197, 154, 14}, 3, "xZoO" }, { {145, 84, 233, 131, 185}, 5, "kVTpg7k=" }, { {236, 89, 214, 82, 104, 210}, 6, "7FnWUmjS" }, { {136, 76, 3, 211, 19, 69, 153}, 7, "iEwD0xNFmQ==" }, { {24, 108, 157, 81, 236, 126, 166}, 7, "GGydUex+pg==" }, { {34, 31, 17, 74, 171, 58, 153, 97, 220, 107, 33, 180}, 12, "Ih8RSqs6mWHcayG0" }, { {134, 135, 55, 174, 149, 208, 201, 195, 33, 178, 156, 142, 147}, 13, "hoc3rpXQycMhspyOkw==" }, { {253, 196, 137, 131, 245, 24, 36, 3, 175, 218, 217, 61, 201, 253}, 14, "/cSJg/UYJAOv2tk9yf0=" }, { {4, 107, 94, 241, 23, 242, 55, 125, 205, 218, 117, 10, 75, 11, 110}, 15, "BGte8RfyN33N2nUKSwtu" }, { {249, 94, 168, 68, 121, 67, 209, 4, 191, 162, 57, 44, 244, 185, 211, 159}, 16, "+V6oRHlD0QS/ojks9LnTnw==" }, }; // 3 bytes of data generates 4 characters in the base64 string const size_t BASE64_BUFFER_SIZE = (ITF_ARRAY_SIZE(g_base64Tests[0].m_data) + 2) / 3 * 4 + 1; const char* g_invalidBase64Strings [] = { " ", "a===", "avGhe", "7Fn[UmjS", "avGhe57==", }; } TEST(StringHelpers, test_StrEncodeBase64) { for (size_t testInd = 0; testInd < ITF_ARRAY_SIZE(g_base64Tests); testInd++) { const Base64TestData& currentTest = g_base64Tests[testInd]; // Called with no buffer size_t expectedLength = StrEncodeBase64(currentTest.m_data, currentTest.m_dataSize, nullptr, 0); EXPECT_EQ(expectedLength, StrLength(currentTest.m_base64String)) << "Test " << testInd << " failed."; // Called with a buffer that is large enough char base64Buffer [BASE64_BUFFER_SIZE] = "xxx"; size_t encodedLength = StrEncodeBase64(currentTest.m_data, currentTest.m_dataSize, base64Buffer, ITF_ARRAY_SIZE(base64Buffer)); EXPECT_EQ(encodedLength, expectedLength) << "Test " << testInd << " failed."; EXPECT_EQ(0, strcmp(currentTest.m_base64String, base64Buffer)) << "Test " << testInd << " failed."; // Called with a buffer that is too small char base64SmallBuffer [BASE64_BUFFER_SIZE] = "xxx"; size_t smallBufferSize = (StrLength(currentTest.m_base64String) + 1) / 2; encodedLength = StrEncodeBase64(currentTest.m_data, currentTest.m_dataSize, base64SmallBuffer, smallBufferSize); EXPECT_EQ(encodedLength, expectedLength) << "Test " << testInd << " failed."; EXPECT_GE(encodedLength, smallBufferSize) << "Test " << testInd << " failed."; if (smallBufferSize > 0) { EXPECT_EQ('\0', base64SmallBuffer[0]) << "Test " << testInd << " failed."; } } } TEST(StringHelpers, test_StrDecodeBase64) { // Valid base64 strings for (size_t testInd = 0; testInd < ITF_ARRAY_SIZE(g_base64Tests); testInd++) { const Base64TestData& currentTest = g_base64Tests[testInd]; // Called with no buffer size_t expectedSize = 0; bool successful = StrDecodeBase64(currentTest.m_base64String, nullptr, 0, &expectedSize); EXPECT_EQ(expectedSize, currentTest.m_dataSize) << "Test for valid string " << testInd << " failed."; EXPECT_EQ(successful, currentTest.m_dataSize == 0) << "Test for valid string " << testInd << " failed."; // Called with a buffer that is large enough u8 dataBuffer [ITF_ARRAY_SIZE(g_base64Tests[0].m_data)] = {}; size_t resultSize = 0; successful = StrDecodeBase64(currentTest.m_base64String, dataBuffer, ITF_ARRAY_SIZE(dataBuffer), &resultSize); EXPECT_TRUE(successful) << "Test for valid string " << testInd << " failed."; EXPECT_EQ(currentTest.m_dataSize, resultSize) << "Test for valid string " << testInd << " failed."; EXPECT_EQ(0, memcmp(currentTest.m_data, dataBuffer, resultSize)) << "Test for valid string " << testInd << " failed."; // Called with a buffer that is too small u8 dataSmallBuffer [ITF_ARRAY_SIZE(g_base64Tests[0].m_data)] = {}; size_t smallBufferSize = currentTest.m_dataSize / 2; resultSize = 0; successful = StrDecodeBase64(currentTest.m_base64String, dataSmallBuffer, smallBufferSize, &resultSize); EXPECT_EQ(successful, currentTest.m_dataSize == 0) << "Test for valid string " << testInd << " failed."; EXPECT_EQ(currentTest.m_dataSize, resultSize) << "Test for valid string " << testInd << " failed."; } // Invalid base64 strings for (size_t testInd = 0; testInd < ITF_ARRAY_SIZE(g_invalidBase64Strings); testInd++) { const char* currentTestString = g_invalidBase64Strings[testInd]; // Called with no buffer size_t expectedSize = 0; bool successful = StrDecodeBase64(currentTestString, nullptr, 0, &expectedSize); EXPECT_FALSE(successful) << "Test for valid string " << testInd << " failed."; EXPECT_EQ(expectedSize, 0U) << "Test for valid string " << testInd << " failed."; // Called with a buffer u8 dataBuffer [ITF_ARRAY_SIZE(g_base64Tests[0].m_data)] = {}; size_t resultSize = 0; successful = StrDecodeBase64(currentTestString, dataBuffer, ITF_ARRAY_SIZE(dataBuffer), &resultSize); EXPECT_FALSE(successful) << "Test for valid string " << testInd << " failed."; EXPECT_EQ(resultSize, 0U) << "Test for valid string " << testInd << " failed."; } } } // namespace ITF