unit1302: expand the base64 encode/decode tests

Closes #17726
This commit is contained in:
Daniel Stenberg 2025-06-23 22:53:30 +02:00
parent bb50dee510
commit c0cb3485fe
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2

View file

@ -28,145 +28,173 @@
#include <curlx/base64.h>
#include "memdebug.h" /* LAST include file */
struct etest {
const char *input;
size_t ilen;
const char *output;
size_t olen;
};
static CURLcode test_unit1302(char *arg)
{
UNITTEST_BEGIN_SIMPLE
char *output;
unsigned char *decoded;
size_t size = 0;
unsigned char anychar = 'x';
CURLcode rc;
unsigned int i;
rc = curlx_base64_encode("i", 1, &output, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(size == 4, "size should be 4");
verify_memory(output, "aQ==", 4);
Curl_safefree(output);
/* common base64 encoding */
struct etest encode[] = {
{"iiiiii", 1, "aQ==", 4 },
{"iiiiii", 2, "aWk=", 4 },
{"iiiiii", 3, "aWlp", 4 },
{"iiiiii", 4, "aWlpaQ==", 8 },
{"iiiiii", 5, "aWlpaWk=", 8 },
{"iiiiii", 6, "aWlpaWlp", 8 },
{"iiiiiii", 7, "aWlpaWlpaQ==", 12 },
{"iiiiiiii", 8, "aWlpaWlpaWk=", 12 },
{"iiiiiiiii", 9, "aWlpaWlpaWlp", 12 },
{"iiiiiiiiii", 10, "aWlpaWlpaWlpaQ==", 16 },
{"iiiiiiiiiii", 11, "aWlpaWlpaWlpaWk=", 16 },
{"iiiiiiiiiiii", 12, "aWlpaWlpaWlpaWlp", 16 },
{"\xff\x01\xfe\x02", 4, "/wH+Ag==", 8 },
{"\xff\xff\xff\xff", 4, "/////w==", 8 },
{"\x00\x00\x00\x00", 4, "AAAAAA==", 8 },
{"\x00\x00\x00\x00", 1, "AA==", 4 },
};
rc = curlx_base64_encode("ii", 2, &output, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(size == 4, "size should be 4");
verify_memory(output, "aWk=", 4);
Curl_safefree(output);
/* base64 URL encoding */
struct etest url[] = {
{"", 0, "", 0 },
{"iiiiiiiiiii", 1, "aQ", 2 },
{"iiiiiiiiiii", 2, "aWk", 3 },
{"iiiiiiiiiii", 3, "aWlp", 4 },
{"iiiiiiiiiii", 4, "aWlpaQ", 6 },
{"iiiiiiiiiii", 5, "aWlpaWk", 7 },
{"iiiiiiiiiii", 6, "aWlpaWlp", 8 },
{"iiiiiiiiiii", 7, "aWlpaWlpaQ", 10 },
{"iiiiiiiiiii", 8, "aWlpaWlpaWk", 11 },
{"iiiiiiiiiii", 9, "aWlpaWlpaWlp", 12 },
{"iiiiiiiiiii", 10, "aWlpaWlpaWlpaQ", 14 },
{"iiiiiiiiiii", 11, "aWlpaWlpaWlpaWk", 15 },
{"iiiiiiiiiiii", 12, "aWlpaWlpaWlpaWlp", 16 },
{"\xff\x01\xfe\x02", 4, "_wH-Ag", 6 },
{"\xff\xff\xff\xff", 4, "_____w", 6 },
{"\xff\x00\xff\x00", 4, "_wD_AA", 6 },
{"\x00\xff\x00\xff", 4, "AP8A_w", 6 },
{"\x00\x00\x00\x00", 4, "AAAAAA", 6 },
{"\x00", 1, "AA", 2 },
{"\x01", 1, "AQ", 2 },
{"\x02", 1, "Ag", 2 },
{"\x03", 1, "Aw", 2 },
{"\x04", 1, "BA", 2 },
{"\x05", 1, "BQ", 2 },
{"\x06", 1, "Bg", 2 },
{"\x07", 1, "Bw", 2 },
{"\x08", 1, "CA", 2 },
{"\x09", 1, "CQ", 2 },
{"\x0a", 1, "Cg", 2 },
{"\x0b", 1, "Cw", 2 },
{"\x0c", 1, "DA", 2 },
{"\x0d", 1, "DQ", 2 },
{"\x0e", 1, "Dg", 2 },
{"\x0f", 1, "Dw", 2 },
{"\x10", 1, "EA", 2 },
};
rc = curlx_base64_encode("iii", 3, &output, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(size == 4, "size should be 4");
verify_memory(output, "aWlp", 4);
Curl_safefree(output);
/* bad decode inputs */
struct etest badecode[] = {
{"", 0, "", 0 }, /* no dats means error */
{"", 0, "a", 1 }, /* data is too short */
{"", 0, "aQ", 2 }, /* data is too short */
{"", 0, "aQ=", 3 }, /* data is too short */
{"", 0, "====", 1 }, /* data is only padding characters */
{"", 0, "====", 2 }, /* data is only padding characters */
{"", 0, "====", 3 }, /* data is only padding characters */
{"", 0, "====", 4 }, /* data is only padding characters */
{"", 0, "a===", 4 }, /* contains three padding characters */
{"", 0, "a=Q=", 4 }, /* contains a padding character mid input */
{"", 0, "aWlpa=Q=", 8 }, /* contains a padding character mid input */
{"", 0, "a\x1f==", 4 }, /* contains illegal base64 character */
{"", 0, "abcd ", 5 }, /* contains illegal base64 character */
{"", 0, "abcd ", 6 }, /* contains illegal base64 character */
{"", 0, " abcd", 5 }, /* contains illegal base64 character */
{"", 0, "_abcd", 5 }, /* contains illegal base64 character */
{"", 0, "abcd-", 5 }, /* contains illegal base64 character */
{"", 0, "abcd_", 5 }, /* contains illegal base64 character */
{"", 0, "aWlpaWlpaQ==-", 17}, /* bad character after padding */
{"", 0, "aWlpaWlpaQ==_", 17}, /* bad character after padding */
{"", 0, "aWlpaWlpaQ== ", 17}, /* bad character after padding */
{"", 0, "aWlpaWlpaQ=", 15} /* unaligned size, missing a padding char */
};
rc = curlx_base64_encode("iiii", 4, &output, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(size == 8, "size should be 8");
verify_memory(output, "aWlpaQ==", 8);
Curl_safefree(output);
for(i = 0 ; i < CURL_ARRAYSIZE(encode); i++) {
struct etest *e = &encode[i];
char *out;
unsigned char *decoded;
size_t olen;
size_t dlen;
rc = curlx_base64_encode("\xff\x01\xfe\x02", 4, &output, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(size == 8, "size should be 8");
verify_memory(output, "/wH+Ag==", 8);
Curl_safefree(output);
/* first encode */
rc = curlx_base64_encode(e->input, e->ilen, &out, &olen);
abort_unless(rc == CURLE_OK, "return code should be CURLE_OK");
abort_unless(olen == e->olen, "wrong output size");
if(memcmp(out, e->output, e->olen)) {
fprintf(stderr, "Test %u encoded badly\n", i);
unitfail++;
}
Curl_safefree(out);
rc = curlx_base64url_encode("\xff\x01\xfe\x02", 4, &output, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(size == 6, "size should be 6");
verify_memory(output, "_wH-Ag", 6);
Curl_safefree(output);
/* then verify decode */
rc = curlx_base64_decode(e->output, &decoded, &dlen);
if(rc != CURLE_OK) {
fprintf(stderr, "Test %u URL decode returned %d\n", i, (int)rc);
unitfail++;
}
if(dlen != e->ilen) {
fprintf(stderr, "Test %u URL decode output length %d instead of %d\n",
i, (int)dlen, (int)e->ilen);
unitfail++;
}
if(memcmp(decoded, e->input, dlen)) {
fprintf(stderr, "Test %u URL decoded badly. Got '%s', expected '%s'\n",
i, decoded, e->input);
unitfail++;
}
rc = curlx_base64url_encode("iiii", 4, &output, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(size == 6, "size should be 6");
verify_memory(output, "aWlpaQ", 6);
Curl_safefree(output);
Curl_safefree(decoded);
}
/* 0 length makes it do strlen() */
rc = curlx_base64_encode("iiii", 0, &output, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(size == 8, "size should be 8");
verify_memory(output, "aWlpaQ==", 8);
Curl_safefree(output);
for(i = 0 ; i < CURL_ARRAYSIZE(url); i++) {
struct etest *e = &url[i];
char *out;
size_t olen;
rc = curlx_base64url_encode(e->input, e->ilen, &out, &olen);
abort_unless(rc == CURLE_OK, "return code should be CURLE_OK");
if(olen != e->olen) {
fprintf(stderr, "Test %u URL encoded output length %d instead of %d\n",
i, (int)olen, (int)e->olen);
}
if(memcmp(out, e->output, e->olen)) {
fprintf(stderr, "Test %u URL encoded badly. Got '%s', expected '%s'\n",
i, out, e->output);
unitfail++;
}
Curl_safefree(out);
}
rc = curlx_base64_encode("", 0, &output, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(size == 0, "size should be 0");
fail_unless(output && !output[0], "output should be a zero-length string");
Curl_safefree(output);
for(i = 0 ; i < CURL_ARRAYSIZE(badecode); i++) {
struct etest *e = &badecode[i];
unsigned char *decoded;
size_t dlen;
rc = curlx_base64url_encode("", 0, &output, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(size == 0, "size should be 0");
fail_unless(output && !output[0], "output should be a zero-length string");
Curl_safefree(output);
rc = curlx_base64_decode("aWlpaQ==", &decoded, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(size == 4, "size should be 4");
verify_memory(decoded, "iiii", 4);
Curl_safefree(decoded);
rc = curlx_base64_decode("aWlp", &decoded, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(size == 3, "size should be 3");
verify_memory(decoded, "iii", 3);
Curl_safefree(decoded);
rc = curlx_base64_decode("aWk=", &decoded, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(size == 2, "size should be 2");
verify_memory(decoded, "ii", 2);
Curl_safefree(decoded);
rc = curlx_base64_decode("aQ==", &decoded, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(size == 1, "size should be 1");
verify_memory(decoded, "i", 2);
Curl_safefree(decoded);
/* This is illegal input as the data is too short */
size = 1; /* not zero */
decoded = &anychar; /* not NULL */
rc = curlx_base64_decode("aQ", &decoded, &size);
fail_unless(rc == CURLE_BAD_CONTENT_ENCODING,
"return code should be CURLE_BAD_CONTENT_ENCODING");
fail_unless(size == 0, "size should be 0");
fail_if(decoded, "returned pointer should be NULL");
/* This is illegal input as it contains three padding characters */
size = 1; /* not zero */
decoded = &anychar; /* not NULL */
rc = curlx_base64_decode("a===", &decoded, &size);
fail_unless(rc == CURLE_BAD_CONTENT_ENCODING,
"return code should be CURLE_BAD_CONTENT_ENCODING");
fail_unless(size == 0, "size should be 0");
fail_if(decoded, "returned pointer should be NULL");
/* This is illegal input as it contains a padding character mid input */
size = 1; /* not zero */
decoded = &anychar; /* not NULL */
rc = curlx_base64_decode("a=Q=", &decoded, &size);
fail_unless(rc == CURLE_BAD_CONTENT_ENCODING,
"return code should be CURLE_BAD_CONTENT_ENCODING");
fail_unless(size == 0, "size should be 0");
fail_if(decoded, "returned pointer should be NULL");
/* This is also illegal input as it contains a padding character mid input */
size = 1; /* not zero */
decoded = &anychar; /* not NULL */
rc = curlx_base64_decode("aWlpa=Q=", &decoded, &size);
fail_unless(rc == CURLE_BAD_CONTENT_ENCODING,
"return code should be CURLE_BAD_CONTENT_ENCODING");
fail_unless(size == 0, "size should be 0");
fail_if(decoded, "returned pointer should be NULL");
/* This is garbage input as it contains an illegal base64 character */
size = 1; /* not zero */
decoded = &anychar; /* not NULL */
rc = curlx_base64_decode("a\x1f==", &decoded, &size);
fail_unless(rc == CURLE_BAD_CONTENT_ENCODING,
"return code should be CURLE_BAD_CONTENT_ENCODING");
fail_unless(size == 0, "size should be 0");
fail_if(decoded, "returned pointer should be NULL");
/* then verify decode with illegal inputs */
rc = curlx_base64_decode(e->output, &decoded, &dlen);
if(rc != CURLE_BAD_CONTENT_ENCODING) {
fprintf(stderr, "Test %u URL bad decoded badly. "
"Returned '%d', expected '%d'\n",
i, (int)rc, CURLE_BAD_CONTENT_ENCODING);
unitfail++;
}
}
UNITTEST_END_SIMPLE
}