| /* This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| /* |
| * test_string.c |
| * |
| * Tests Strings. |
| * |
| */ |
| |
| #include "testutil.h" |
| #include "testutil_nss.h" |
| |
| static void *plContext = NULL; |
| |
| static void |
| createString( |
| PKIX_PL_String **testString, |
| PKIX_UInt32 format, |
| char *stringAscii, |
| PKIX_UInt32 length) |
| { |
| PKIX_TEST_STD_VARS(); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(format, stringAscii, length, testString, plContext)); |
| |
| cleanup: |
| |
| PKIX_TEST_RETURN(); |
| } |
| |
| static void |
| createStringOther( |
| PKIX_PL_String **testEscAscii, |
| PKIX_PL_String **testUtf16, |
| PKIX_PL_String **ampString, |
| PKIX_PL_String **testDebugAscii, |
| PKIX_PL_String **testNullString, |
| PKIX_UInt32 *utf16data) |
| { |
| char *nullText = "Hi� there!"; |
| |
| char *escAsciiString = |
| "¡𐀀࿿􀀁"; |
| |
| char *debugAsciiString = |
| "string with
newlines and	tabs"; |
| |
| char *utfAmp = "\x00&"; |
| |
| PKIX_TEST_STD_VARS(); |
| |
| createString(testEscAscii, |
| PKIX_ESCASCII, |
| escAsciiString, |
| PL_strlen(escAsciiString)); |
| |
| createString(testUtf16, PKIX_UTF16, (char *)utf16data, 12); |
| |
| createString(ampString, PKIX_UTF16, utfAmp, 2); |
| |
| createString(testDebugAscii, |
| PKIX_ESCASCII_DEBUG, |
| debugAsciiString, |
| PL_strlen(debugAsciiString)); |
| |
| createString(testNullString, |
| PKIX_ESCASCII_DEBUG, |
| nullText, |
| PL_strlen(nullText)); |
| |
| goto cleanup; |
| |
| cleanup: |
| |
| PKIX_TEST_RETURN(); |
| } |
| |
| static void |
| testGetEncoded( |
| PKIX_PL_String *testEscAscii, |
| PKIX_PL_String *testString0, |
| PKIX_PL_String *testDebugAscii, |
| PKIX_PL_String *testNullString, |
| PKIX_UInt32 *utf16data) |
| { |
| char *temp = NULL; |
| void *dest = NULL; |
| void *dest2 = NULL; |
| char *plainText = "string with\nnewlines and\ttabs"; |
| PKIX_UInt32 length, length2, i; |
| |
| PKIX_TEST_STD_VARS(); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_GetEncoded(testEscAscii, |
| PKIX_UTF16, |
| &dest, |
| &length, |
| plContext)); |
| for (i = 0; i < length; i++) { |
| if (((char *)dest)[i] != ((char *)utf16data)[i]) { |
| testError("UTF-16 Data Differs from Source"); |
| printf("%d-th char is different -%c-%c-\n", i, |
| ((char *)dest)[i], ((char *)utf16data)[i]); |
| } |
| } |
| |
| length = 0; |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(dest, plContext)); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_GetEncoded(testNullString, |
| PKIX_UTF16, |
| &dest, |
| &length, |
| plContext)); |
| |
| length = 0; |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(dest, plContext)); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_GetEncoded(testString0, |
| PKIX_ESCASCII_DEBUG, |
| &dest, |
| &length, |
| plContext)); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_GetEncoded(testDebugAscii, |
| PKIX_ESCASCII_DEBUG, |
| &dest2, |
| &length2, |
| plContext)); |
| |
| for (i = 0; (i < length) && (i < length2); i++) |
| if (((char *)dest)[i] != ((char *)dest2)[i]) { |
| testError("Equivalent strings are unequal"); |
| break; |
| } |
| |
| length = 0; |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(dest, plContext)); |
| length2 = 0; |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(dest2, plContext)); |
| |
| temp = PKIX_String2ASCII(testDebugAscii, plContext); |
| if (temp) { |
| if (PL_strcmp(plainText, temp) != 0) |
| testError("Debugged ASCII does not match " |
| "equivalent EscAscii"); |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext)); |
| } |
| |
| cleanup: |
| |
| PKIX_TEST_RETURN(); |
| } |
| |
| static void |
| testSprintf(void) |
| { |
| PKIX_Int32 x = 0xCAFE; |
| PKIX_Int32 y = -12345; |
| PKIX_PL_String *testString = NULL; |
| PKIX_PL_String *formatString = NULL; |
| PKIX_PL_String *sprintfString = NULL; |
| char *plainText = "Testing Sprintf"; |
| char *format = "%s %x %u %d"; |
| char *convertedFormat = "%s %lx %lu %ld"; |
| char *temp = NULL; |
| char *temp2 = NULL; |
| |
| PKIX_TEST_STD_VARS(); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create( |
| PKIX_ESCASCII, |
| plainText, |
| PL_strlen(plainText), |
| &testString, |
| plContext)); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create( |
| PKIX_ESCASCII, |
| format, |
| 11, |
| &formatString, |
| plContext)); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Sprintf(&sprintfString, |
| plContext, |
| formatString, |
| testString, x, y, y)); |
| PKIX_TEST_DECREF_BC(testString); |
| |
| temp = PR_smprintf(convertedFormat, plainText, x, y, y); |
| temp2 = PKIX_String2ASCII(sprintfString, plContext); |
| |
| if (PL_strcmp(temp, temp2) != 0) |
| testError("Sprintf produced incorrect output"); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext)); |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp2, plContext)); |
| |
| PKIX_TEST_DECREF_BC(sprintfString); |
| |
| PKIX_TEST_DECREF_BC(formatString); |
| |
| cleanup: |
| |
| PKIX_TEST_RETURN(); |
| } |
| |
| static void |
| testErrorHandling(void) |
| { |
| char *debugAsciiString = |
| "string with
newlines and	tabs"; |
| |
| PKIX_PL_String *testString = NULL; |
| |
| PKIX_TEST_STD_VARS(); |
| |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create( |
| PKIX_ESCASCII, |
| NULL, |
| 50, |
| &testString, |
| plContext)); |
| |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, |
| "blah", 4, NULL, plContext)); |
| |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_Sprintf(&testString, plContext, NULL)); |
| |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_GetString(0, NULL, &testString, plContext)); |
| |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_GetString(0, "blah", 0, plContext)); |
| |
| /* ---------------------------- */ |
| subTest("Unicode Error Handling"); |
| |
| /* &#x must be followed by 4 hexadecimal digits */ |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create( |
| PKIX_ESCASCII, |
| "k;", |
| 7, |
| &testString, |
| plContext)); |
| |
| /* &#x must be followed by 4 hexadecimal digits */ |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create( |
| PKIX_ESCASCII, |
| "abc�", |
| 8, |
| &testString, |
| plContext)); |
| |
| /* &#x must be between 00010000-0010FFFF */ |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create( |
| PKIX_ESCASCII, |
| "�", |
| 11, |
| &testString, |
| plContext)); |
| |
| /* &#x must be followed by 8 hexadecimal digits */ |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create( |
| PKIX_ESCASCII, |
| "က", |
| 10, |
| &testString, |
| plContext)); |
| |
| /* &#x must be followed by 8 hexadecimal digits */ |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create( |
| PKIX_ESCASCII, |
| "m00;", |
| 10, |
| &testString, |
| plContext)); |
| |
| /* Byte values D800-DFFF are reserved */ |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create( |
| PKIX_ESCASCII, |
| "�", |
| 7, |
| &testString, |
| plContext)); |
| |
| /* Can't use &#x for regular characters */ |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create( |
| PKIX_ESCASCII, |
| "2", |
| 7, |
| &testString, |
| plContext)); |
| |
| /* Can't use non-printable characters */ |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create( |
| PKIX_ESCASCII, |
| "\xA1", |
| 1, |
| &testString, |
| plContext)); |
| |
| /* Only legal \\ characters are \\, u and U */ |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create( |
| PKIX_ESCASCII, |
| "&blah", |
| 5, |
| &testString, |
| plContext)); |
| |
| /* Surrogate pairs must be legal */ |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create( |
| PKIX_UTF16, |
| "\xd8\x00\x0\x66", |
| 4, |
| &testString, |
| plContext)); |
| |
| /* Debugged EscASCII should not be accepted as EscASCII */ |
| PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create( |
| PKIX_ESCASCII, |
| debugAsciiString, |
| PL_strlen(debugAsciiString), |
| &testString, |
| plContext)); |
| cleanup: |
| |
| PKIX_TEST_RETURN(); |
| } |
| |
| static void |
| testDestroy( |
| PKIX_PL_String *string) |
| { |
| PKIX_TEST_STD_VARS(); |
| |
| PKIX_TEST_DECREF_BC(string); |
| |
| cleanup: |
| |
| PKIX_TEST_RETURN(); |
| } |
| |
| int |
| test_string(int argc, char *argv[]) |
| { |
| |
| PKIX_PL_String *testString[6] = { NULL }; |
| PKIX_PL_String *testNullString = NULL; |
| PKIX_PL_String *testDebugAscii = NULL; |
| PKIX_PL_String *testEscAscii = NULL; |
| PKIX_PL_String *testUtf16 = NULL; |
| PKIX_PL_String *ampString = NULL; |
| unsigned char utf16Data[] = { 0x00, 0xA1, 0xD8, 0x00, |
| 0xDC, 0x00, 0x0F, 0xFF, |
| 0xDB, 0xC0, 0xDC, 0x01 }; |
| PKIX_UInt32 i, size = 6; |
| |
| char *plainText[6] = { |
| "string with\nnewlines and\ttabs", |
| "Not an escaped char: &#x0012;", |
| "Encode & with &amp; in ASCII", |
| "¡", |
| "&", |
| "string with\nnewlines and\ttabs" |
| }; |
| |
| PKIX_UInt32 actualMinorVersion; |
| PKIX_UInt32 j = 0; |
| |
| PKIX_TEST_STD_VARS(); |
| |
| startTests("Strings"); |
| |
| PKIX_TEST_EXPECT_NO_ERROR( |
| PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext)); |
| |
| subTest("PKIX_PL_String_Create <ascii format>"); |
| for (i = 0; i < size; i++) { |
| testString[i] = NULL; |
| createString(&testString[i], |
| PKIX_ESCASCII, |
| plainText[i], |
| PL_strlen(plainText[i])); |
| } |
| |
| subTest("PKIX_PL_String_Create <other formats>"); |
| createStringOther(&testEscAscii, |
| &testUtf16, |
| &String, |
| &testDebugAscii, |
| &testNullString, |
| (PKIX_UInt32 *)utf16Data); |
| |
| PKIX_TEST_EQ_HASH_TOSTR_DUP(testString[0], |
| testString[5], |
| testString[1], |
| plainText[0], |
| String, |
| PKIX_TRUE); |
| |
| subTest("PKIX_PL_String_GetEncoded"); |
| testGetEncoded(testEscAscii, |
| testString[0], |
| testDebugAscii, |
| testNullString, |
| (PKIX_UInt32 *)utf16Data); |
| |
| subTest("PKIX_PL_Sprintf"); |
| testSprintf(); |
| |
| subTest("PKIX_PL_String_Create <error_handling>"); |
| testErrorHandling(); |
| |
| subTest("PKIX_PL_String_Destroy"); |
| for (i = 0; i < size; i++) { |
| testDestroy(testString[i]); |
| } |
| testDestroy(testEscAscii); |
| testDestroy(testUtf16); |
| testDestroy(ampString); |
| testDestroy(testDebugAscii); |
| testDestroy(testNullString); |
| |
| cleanup: |
| |
| PKIX_Shutdown(plContext); |
| |
| PKIX_TEST_RETURN(); |
| |
| endTests("String"); |
| |
| return (0); |
| } |