aboutsummaryrefslogtreecommitdiffstats
path: root/libparc/parc/algol/test/test_parc_Base64.c
diff options
context:
space:
mode:
Diffstat (limited to 'libparc/parc/algol/test/test_parc_Base64.c')
-rwxr-xr-xlibparc/parc/algol/test/test_parc_Base64.c414
1 files changed, 414 insertions, 0 deletions
diff --git a/libparc/parc/algol/test/test_parc_Base64.c b/libparc/parc/algol/test/test_parc_Base64.c
new file mode 100755
index 00000000..4509ded3
--- /dev/null
+++ b/libparc/parc/algol/test/test_parc_Base64.c
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+#include <LongBow/unit-test.h>
+
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Framework.
+#include "../parc_Base64.c"
+#include <parc/algol/parc_SafeMemory.h>
+
+LONGBOW_TEST_RUNNER(parc_Base64)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified, but all tests should be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Local);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(parc_Base64)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(parc_Base64)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, parcBase64_Decode);
+ LONGBOW_RUN_TEST_CASE(Global, parcBase64_Decode_Linefeeds);
+ LONGBOW_RUN_TEST_CASE(Global, parcBase64_Encode);
+ LONGBOW_RUN_TEST_CASE(Global, parcBase64_Encode_Binary);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks %d memory allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+static struct testvector_s {
+ char *plaintext;
+ char *encoded;
+} testvector[] = {
+ // Test vectors from RFC 4648
+ { .plaintext = "", .encoded = "" },
+ { .plaintext = "f", .encoded = "Zg==" },
+ { .plaintext = "fo", .encoded = "Zm8=" },
+ { .plaintext = "foo", .encoded = "Zm9v" },
+ { .plaintext = "foob", .encoded = "Zm9vYg==" },
+ { .plaintext = "fooba", .encoded = "Zm9vYmE=" },
+ { .plaintext = "foobar", .encoded = "Zm9vYmFy" },
+ { .plaintext = NULL, .encoded = NULL }
+};
+
+LONGBOW_TEST_CASE(Global, parcBase64_Decode)
+{
+ int i = 0;
+ while (testvector[i].plaintext != NULL) {
+ PARCBufferComposer *input = parcBufferComposer_Create();
+ PARCBufferComposer *truth = parcBufferComposer_Create();
+ PARCBufferComposer *output = parcBufferComposer_Create();
+
+ parcBufferComposer_PutString(input, testvector[i].encoded);
+ PARCBuffer *inputBuffer = parcBufferComposer_ProduceBuffer(input);
+ parcBufferComposer_PutString(truth, testvector[i].plaintext);
+ PARCBuffer *truthBuffer = parcBufferComposer_ProduceBuffer(truth);
+
+ parcBase64_Decode(output, parcBufferComposer_GetBuffer(input));
+ PARCBuffer *outputBuffer = parcBufferComposer_ProduceBuffer(output);
+
+ assertTrue(parcBuffer_Equals(truthBuffer, outputBuffer),
+ "encoding, expected '%s' got '%s'",
+ parcBuffer_ToHexString(truthBuffer),
+ parcBuffer_ToHexString(outputBuffer));
+
+ i++;
+
+ parcBuffer_Release(&inputBuffer);
+ parcBuffer_Release(&truthBuffer);
+ parcBuffer_Release(&outputBuffer);
+
+ parcBufferComposer_Release(&input);
+ parcBufferComposer_Release(&output);
+ parcBufferComposer_Release(&truth);
+ }
+}
+
+LONGBOW_TEST_CASE(Global, parcBase64_Decode_Linefeeds)
+{
+ PARCBufferComposer *input = parcBufferComposer_Create();
+ PARCBufferComposer *truth = parcBufferComposer_Create();
+ PARCBufferComposer *output = parcBufferComposer_Create();
+
+ char plaintext[] = "It was a dark and stormy night, and all through the code not bit was stirring.\x0A";
+ char encoded_with_crlf[] = "SXQg" "\x0D\x0A" "d2FzIGEgZGFyayBhbmQgc3Rvcm15IG5pZ2h0LCBhbmQgYWxsIHRocm91Z2gg" "\x0D\x0A" "dGhlIGNvZGUgbm90IGJpdCB3YXMgc3RpcnJpbmcuCg==";
+
+ parcBufferComposer_PutString(input, encoded_with_crlf);
+ PARCBuffer *inputBuffer = parcBufferComposer_ProduceBuffer(input);
+
+ parcBufferComposer_PutString(truth, plaintext);
+ PARCBuffer *truthBuffer = parcBufferComposer_ProduceBuffer(truth);
+
+ parcBase64_Decode(output, parcBufferComposer_GetBuffer(input));
+ PARCBuffer *outputBuffer = parcBufferComposer_ProduceBuffer(output);
+ assertTrue(parcBuffer_Equals(truthBuffer, outputBuffer),
+ "encoding, expected '%s' got '%s'",
+ parcBuffer_ToHexString(truthBuffer),
+ parcBuffer_ToHexString(outputBuffer));
+
+ parcBuffer_Release(&inputBuffer);
+ parcBuffer_Release(&truthBuffer);
+ parcBuffer_Release(&outputBuffer);
+
+ parcBufferComposer_Release(&input);
+ parcBufferComposer_Release(&output);
+ parcBufferComposer_Release(&truth);
+}
+
+
+LONGBOW_TEST_CASE(Global, parcBase64_Encode)
+{
+ int i = 0;
+ while (testvector[i].plaintext != NULL) {
+ PARCBufferComposer *input = parcBufferComposer_Create();
+ PARCBufferComposer *truth = parcBufferComposer_Create();
+ PARCBufferComposer *output = parcBufferComposer_Create();
+
+ parcBufferComposer_PutString(input, testvector[i].plaintext);
+ PARCBuffer *inputBuffer = parcBufferComposer_ProduceBuffer(input);
+ parcBufferComposer_PutString(truth, testvector[i].encoded);
+ PARCBuffer *truthBuffer = parcBufferComposer_ProduceBuffer(truth);
+
+ parcBase64_Encode(output, parcBufferComposer_GetBuffer(input));
+ PARCBuffer *outputBuffer = parcBufferComposer_ProduceBuffer(output);
+ assertTrue(parcBuffer_Equals(truthBuffer, outputBuffer),
+ "encoding, expected '%s' got '%s'",
+ parcBuffer_ToHexString(truthBuffer),
+ parcBuffer_ToHexString(outputBuffer));
+
+ i++;
+
+ parcBuffer_Release(&inputBuffer);
+ parcBuffer_Release(&truthBuffer);
+ parcBuffer_Release(&outputBuffer);
+
+ parcBufferComposer_Release(&input);
+ parcBufferComposer_Release(&output);
+ parcBufferComposer_Release(&truth);
+ }
+}
+
+LONGBOW_TEST_CASE(Global, parcBase64_Encode_Binary)
+{
+ uint8_t zero[] = { 0 };
+
+ // 1 2 3 4 5 6 7
+ char *truthvector[] = { "AA==", "AAA=", "AAAA", "AAAAAA==", "AAAAAAA=", "AAAAAAAA", "AAAAAAAAAA==" };
+
+ for (int i = 0; i < sizeof(truthvector) / sizeof(truthvector[0]); i++) {
+ PARCBufferComposer *input = parcBufferComposer_Create();
+ PARCBufferComposer *truth = parcBufferComposer_Create();
+ PARCBufferComposer *output = parcBufferComposer_Create();
+
+ parcBufferComposer_PutArray(truth, (uint8_t *) truthvector[i], strlen(truthvector[i]));
+ PARCBuffer *truthBuffer = parcBufferComposer_ProduceBuffer(truth);
+
+ // just keep apending a zero to make it longer
+ parcBuffer_SetLimit(parcBufferComposer_GetBuffer(input), parcBuffer_Capacity(parcBufferComposer_GetBuffer(input)));
+ parcBuffer_SetPosition(parcBufferComposer_GetBuffer(input), i);
+ parcBufferComposer_PutArray(input, zero, 1);
+ PARCBuffer *inputBuffer = parcBufferComposer_ProduceBuffer(input);
+
+ parcBase64_Encode(output, parcBufferComposer_GetBuffer(input));
+ PARCBuffer *outputBuffer = parcBufferComposer_ProduceBuffer(output);
+
+ assertTrue(parcBuffer_Equals(truthBuffer, outputBuffer),
+ "encoding, expected '%s' got '%s'",
+ parcBuffer_ToHexString(truthBuffer),
+ parcBuffer_ToHexString(outputBuffer));
+
+ parcBuffer_Release(&inputBuffer);
+ parcBuffer_Release(&truthBuffer);
+ parcBuffer_Release(&outputBuffer);
+
+ parcBufferComposer_Release(&input);
+ parcBufferComposer_Release(&output);
+ parcBufferComposer_Release(&truth);
+ }
+}
+
+LONGBOW_TEST_FIXTURE(Local)
+{
+ LONGBOW_RUN_TEST_CASE(Local, encodeWithPad_0);
+ LONGBOW_RUN_TEST_CASE(Local, encodeWithPad_1);
+ LONGBOW_RUN_TEST_CASE(Local, encodeWithPad_2);
+ LONGBOW_RUN_TEST_CASE(Local, decode_invalid);
+ LONGBOW_RUN_TEST_CASE(Local, decode_1);
+ LONGBOW_RUN_TEST_CASE(Local, decode_2);
+ LONGBOW_RUN_TEST_CASE(Local, decode_3);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Local)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Local)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks %d memory allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+/**
+ * This will encode "foo"
+ */
+LONGBOW_TEST_CASE(Local, encodeWithPad_0)
+{
+ PARCBufferComposer *output = parcBufferComposer_Create();
+ uint8_t input[] = "foobar";
+ PARCBufferComposer *truth = parcBufferComposer_Create();
+ parcBufferComposer_PutString(truth, "Zm9v");
+ PARCBuffer *truthBuffer = parcBufferComposer_ProduceBuffer(truth);
+
+ _encodeWithPad(output, input, 0);
+ PARCBuffer *outputBuffer = parcBufferComposer_ProduceBuffer(output);
+ assertTrue(parcBuffer_Equals(truthBuffer, outputBuffer),
+ "Failed 3-byte encode, expected '%s' got '%s'",
+ parcBuffer_ToHexString(truthBuffer),
+ parcBuffer_ToHexString(outputBuffer));
+
+ parcBuffer_Release(&truthBuffer);
+ parcBuffer_Release(&outputBuffer);
+
+ parcBufferComposer_Release(&output);
+ parcBufferComposer_Release(&truth);
+}
+
+/**
+ * This will encode "fo" because we tell it there's 1 pad byte
+ */
+LONGBOW_TEST_CASE(Local, encodeWithPad_1)
+{
+ PARCBufferComposer *output = parcBufferComposer_Create();
+ uint8_t input[] = "foobar";
+ PARCBufferComposer *truth = parcBufferComposer_Create();
+ parcBufferComposer_PutString(truth, "Zm8=");
+ PARCBuffer *truthBuffer = parcBufferComposer_ProduceBuffer(truth);
+
+ _encodeWithPad(output, input, 1);
+ PARCBuffer *outputBuffer = parcBufferComposer_ProduceBuffer(output);
+
+ assertTrue(parcBuffer_Equals(truthBuffer, outputBuffer),
+ "Failed 3-byte encode, expected '%s' got '%s'",
+ parcBuffer_ToHexString(truthBuffer),
+ parcBuffer_ToHexString(outputBuffer));
+
+ parcBuffer_Release(&truthBuffer);
+ parcBuffer_Release(&outputBuffer);
+
+ parcBufferComposer_Release(&output);
+ parcBufferComposer_Release(&truth);
+}
+
+/**
+ * This will encode "f" because we tell it there's 2 pad byte
+ */
+LONGBOW_TEST_CASE(Local, encodeWithPad_2)
+{
+ PARCBufferComposer *output = parcBufferComposer_Create();
+ uint8_t input[] = "foobar";
+ PARCBufferComposer *truth = parcBufferComposer_Create();
+ parcBufferComposer_PutString(truth, "Zg==");
+ PARCBuffer *truthBuffer = parcBufferComposer_ProduceBuffer(truth);
+
+ _encodeWithPad(output, input, 2);
+ PARCBuffer *outputBuffer = parcBufferComposer_ProduceBuffer(output);
+
+ assertTrue(parcBuffer_Equals(truthBuffer, outputBuffer),
+ "Failed 3-byte encode, expected '%s' got '%s'",
+ parcBuffer_ToHexString(truthBuffer),
+ parcBuffer_ToHexString(outputBuffer));
+
+ parcBuffer_Release(&truthBuffer);
+ parcBuffer_Release(&outputBuffer);
+
+ parcBufferComposer_Release(&output);
+ parcBufferComposer_Release(&truth);
+}
+
+
+LONGBOW_TEST_CASE(Local, decode_1)
+{
+ PARCBufferComposer *output = parcBufferComposer_Create();
+ uint8_t input[] = "Zg==";
+ PARCBufferComposer *truth = parcBufferComposer_Create();
+ parcBufferComposer_PutString(truth, "f");
+ PARCBuffer *truthBuffer = parcBufferComposer_ProduceBuffer(truth);
+
+ bool success = _decode(output, input);
+ assertTrue(success, "Valid base64 failed decode");
+
+ PARCBuffer *outputBuffer = parcBufferComposer_ProduceBuffer(output);
+ assertTrue(parcBuffer_Equals(truthBuffer, outputBuffer),
+ "Failed 3-byte encode, expected '%s' got '%s'",
+ parcBuffer_ToHexString(truthBuffer),
+ parcBuffer_ToHexString(outputBuffer));
+
+ parcBuffer_Release(&truthBuffer);
+ parcBuffer_Release(&outputBuffer);
+
+ parcBufferComposer_Release(&output);
+ parcBufferComposer_Release(&truth);
+}
+
+LONGBOW_TEST_CASE(Local, decode_2)
+{
+ PARCBufferComposer *output = parcBufferComposer_Create();
+ uint8_t input[] = "Zm8=";
+ PARCBufferComposer *truth = parcBufferComposer_Create();
+ parcBufferComposer_PutString(truth, "fo");
+ PARCBuffer *truthBuffer = parcBufferComposer_ProduceBuffer(truth);
+
+ bool success = _decode(output, input);
+ assertTrue(success, "Valid base64 failed decode");
+
+ PARCBuffer *outputBuffer = parcBufferComposer_ProduceBuffer(output);
+
+ assertTrue(parcBuffer_Equals(truthBuffer, outputBuffer),
+ "Failed 3-byte encode, expected '%s' got '%s'",
+ parcBuffer_ToHexString(truthBuffer),
+ parcBuffer_ToHexString(outputBuffer));
+
+ parcBuffer_Release(&truthBuffer);
+ parcBuffer_Release(&outputBuffer);
+
+ parcBufferComposer_Release(&output);
+ parcBufferComposer_Release(&truth);
+}
+
+LONGBOW_TEST_CASE(Local, decode_3)
+{
+ PARCBufferComposer *output = parcBufferComposer_Create();
+ uint8_t input[] = "Zm9v";
+ PARCBufferComposer *truth = parcBufferComposer_Create();
+ parcBufferComposer_PutString(truth, "foo");
+ PARCBuffer *truthBuffer = parcBufferComposer_ProduceBuffer(truth);
+
+ bool success = _decode(output, input);
+ assertTrue(success, "Valid base64 failed decode");
+ PARCBuffer *outputBuffer = parcBufferComposer_ProduceBuffer(output);
+
+ assertTrue(parcBuffer_Equals(truthBuffer, outputBuffer),
+ "Failed 3-byte encode, expected '%s' got '%s'",
+ parcBuffer_ToHexString(truthBuffer),
+ parcBuffer_ToHexString(outputBuffer));
+
+ parcBuffer_Release(&truthBuffer);
+ parcBuffer_Release(&outputBuffer);
+
+ parcBufferComposer_Release(&output);
+ parcBufferComposer_Release(&truth);
+}
+
+LONGBOW_TEST_CASE(Local, decode_invalid)
+{
+ PARCBufferComposer *output = parcBufferComposer_Create();
+ uint8_t input[] = "@@@@";
+
+ bool success = _decode(output, input);
+ assertFalse(success, "Invalid base64 somehow decoded");
+
+ parcBufferComposer_Release(&output);
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_Base64);
+ int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}