summaryrefslogtreecommitdiff
path: root/pjlib-util
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2010-10-26 23:53:28 +0000
committerBenny Prijono <bennylp@teluu.com>2010-10-26 23:53:28 +0000
commit224fa2a8db5adfd75e2652afd50ba7517d1b9493 (patch)
tree8bf6f5d1697b40616911ab61b92b6174ad543582 /pjlib-util
parentbce27f19890c7d773a25686732628e421240acc5 (diff)
Fixed #1152 (The base64 decoder should ignore whitespaces in the input). In fact, the base64 decoder now will silently ignore/skip any bad characters.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3356 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib-util')
-rw-r--r--pjlib-util/src/pjlib-util-test/encryption.c103
-rw-r--r--pjlib-util/src/pjlib-util/base64.c58
2 files changed, 91 insertions, 70 deletions
diff --git a/pjlib-util/src/pjlib-util-test/encryption.c b/pjlib-util/src/pjlib-util-test/encryption.c
index 3db0d9a0..b0d3d6a8 100644
--- a/pjlib-util/src/pjlib-util-test/encryption.c
+++ b/pjlib-util/src/pjlib-util-test/encryption.c
@@ -494,6 +494,12 @@ static int crc32_test(void)
return 0;
}
+enum
+{
+ ENCODE = 1,
+ DECODE = 2,
+ ENCODE_DECODE = 3
+};
/*
* Base64 test vectors (RFC 4648)
@@ -502,48 +508,70 @@ static struct base64_test_vec
{
const char *base256;
const char *base64;
+ unsigned flag;
} base64_test_vec[] =
{
{
"",
- ""
+ "",
+ ENCODE_DECODE
},
{
"f",
- "Zg=="
+ "Zg==",
+ ENCODE_DECODE
},
{
"fo",
- "Zm8="
+ "Zm8=",
+ ENCODE_DECODE
},
{
"foo",
- "Zm9v"
+ "Zm9v",
+ ENCODE_DECODE
},
{
"foob",
- "Zm9vYg=="
+ "Zm9vYg==",
+ ENCODE_DECODE
},
{
"fooba",
"Zm9vYmE=",
+ ENCODE_DECODE
},
{
"foobar",
- "Zm9vYmFy"
+ "Zm9vYmFy",
+ ENCODE_DECODE
},
{
"\x14\xfb\x9c\x03\xd9\x7e",
- "FPucA9l+"
+ "FPucA9l+",
+ ENCODE_DECODE
},
{
"\x14\xfb\x9c\x03\xd9",
- "FPucA9k="
+ "FPucA9k=",
+ ENCODE_DECODE
},
{
"\x14\xfb\x9c\x03",
- "FPucAw=="
- }
+ "FPucAw==",
+ ENCODE_DECODE
+ },
+ /* with whitespaces */
+ {
+ "foobar",
+ "Zm9v\r\nYmFy",
+ DECODE
+ },
+ {
+ "foobar",
+ "\nZ\r\nm 9\tv\nYm\nF\ny\n",
+ DECODE
+ },
};
@@ -556,38 +584,43 @@ static int base64_test(void)
PJ_LOG(3, (THIS_FILE, " base64 test.."));
for (i=0; i<PJ_ARRAY_SIZE(base64_test_vec); ++i) {
- /* Encode test */
pj_str_t input;
- int out_len = sizeof(output);
-
- rc = pj_base64_encode((pj_uint8_t*)base64_test_vec[i].base256,
- strlen(base64_test_vec[i].base256),
- output, &out_len);
- if (rc != PJ_SUCCESS)
- return -90;
+ int out_len;
- if (out_len != (int)strlen(base64_test_vec[i].base64))
- return -91;
-
- output[out_len] = '\0';
- if (strcmp(output, base64_test_vec[i].base64) != 0)
- return -92;
+ /* Encode test */
+ if (base64_test_vec[i].flag & ENCODE) {
+ out_len = sizeof(output);
+ rc = pj_base64_encode((pj_uint8_t*)base64_test_vec[i].base256,
+ strlen(base64_test_vec[i].base256),
+ output, &out_len);
+ if (rc != PJ_SUCCESS)
+ return -90;
+
+ if (out_len != (int)strlen(base64_test_vec[i].base64))
+ return -91;
+
+ output[out_len] = '\0';
+ if (strcmp(output, base64_test_vec[i].base64) != 0)
+ return -92;
+ }
/* Decode test */
- out_len = sizeof(output);
- input.ptr = (char*)base64_test_vec[i].base64;
- input.slen = strlen(base64_test_vec[i].base64);
- rc = pj_base64_decode(&input, (pj_uint8_t*)output, &out_len);
- if (rc != PJ_SUCCESS)
- return -95;
+ if (base64_test_vec[i].flag & DECODE) {
+ out_len = sizeof(output);
+ input.ptr = (char*)base64_test_vec[i].base64;
+ input.slen = strlen(base64_test_vec[i].base64);
+ rc = pj_base64_decode(&input, (pj_uint8_t*)output, &out_len);
+ if (rc != PJ_SUCCESS)
+ return -95;
- if (out_len != (int)strlen(base64_test_vec[i].base256))
- return -96;
+ if (out_len != (int)strlen(base64_test_vec[i].base256))
+ return -96;
- output[out_len] = '\0';
+ output[out_len] = '\0';
- if (strcmp(output, base64_test_vec[i].base256) != 0)
- return -97;
+ if (strcmp(output, base64_test_vec[i].base256) != 0)
+ return -97;
+ }
}
return 0;
diff --git a/pjlib-util/src/pjlib-util/base64.c b/pjlib-util/src/pjlib-util/base64.c
index 63371fd4..3702ce3c 100644
--- a/pjlib-util/src/pjlib-util/base64.c
+++ b/pjlib-util/src/pjlib-util/base64.c
@@ -47,7 +47,9 @@ static int base256_char(char c)
else if (c == '/')
return (63);
else {
- pj_assert(!"Should not happen as '=' should have been filtered");
+ /* It *may* happen on bad input, so this is not a good idea.
+ * pj_assert(!"Should not happen as '=' should have been filtered");
+ */
return INV;
}
}
@@ -124,8 +126,8 @@ PJ_DEF(pj_status_t) pj_base64_decode(const pj_str_t *input,
{
const char *buf = input->ptr;
int len = input->slen;
- int i, j;
- int c1, c2, c3, c4;
+ int i, j, k;
+ int c[4];
PJ_ASSERT_RETURN(input && out && out_len, PJ_EINVAL);
@@ -135,42 +137,28 @@ PJ_DEF(pj_status_t) pj_base64_decode(const pj_str_t *input,
PJ_ASSERT_RETURN(*out_len >= PJ_BASE64_TO_BASE256_LEN(len),
PJ_ETOOSMALL);
- for (i=0, j=0; i+3 < len; i+=4) {
- c1 = base256_char(buf[i]);
- c2 = base256_char(buf[i+1]);
- c3 = base256_char(buf[i+2]);
- c4 = base256_char(buf[i+3]);
-
- out[j++] = (pj_uint8_t)((c1<<2) | ((c2 & 0x30)>>4));
- out[j++] = (pj_uint8_t)(((c2 & 0x0F)<<4) | ((c3 & 0x3C)>>2));
- out[j++] = (pj_uint8_t)(((c3 & 0x03)<<6) | (c4 & 0x3F));
- }
-
- if (i < len) {
- c1 = base256_char(buf[i]);
-
- if (i+1 < len)
- c2 = base256_char(buf[i+1]);
- else
- c2 = (INV);
-
- if (i+2 < len)
- c3 = base256_char(buf[i+2]);
- else
- c3 = (INV);
-
- c4 = (INV);
+ for (i=0, j=0; i<len; ) {
+ /* Fill up c, silently ignoring invalid characters */
+ for (k=0; k<4 && i<len; ++k) {
+ do {
+ c[k] = base256_char(buf[i++]);
+ } while (c[k]==INV && i<len);
+ }
- if (c2 != INV) {
- out[j++] = (pj_uint8_t)((c1<<2) | ((c2 & 0x30)>>4));
- if (c3 != INV) {
- out[j++] = (pj_uint8_t)(((c2 & 0x0F)<<4) | ((c3 & 0x3C)>>2));
- if (c4 != INV) {
- out[j++] = (pj_uint8_t)(((c3 & 0x03)<<6) | (c4 & 0x3F));
+ if (k<4) {
+ if (k > 1) {
+ out[j++] = (pj_uint8_t)((c[0]<<2) | ((c[1] & 0x30)>>4));
+ if (k > 2) {
+ out[j++] = (pj_uint8_t)
+ (((c[1] & 0x0F)<<4) | ((c[2] & 0x3C)>>2));
}
}
+ break;
}
-
+
+ out[j++] = (pj_uint8_t)((c[0]<<2) | ((c[1] & 0x30)>>4));
+ out[j++] = (pj_uint8_t)(((c[1] & 0x0F)<<4) | ((c[2] & 0x3C)>>2));
+ out[j++] = (pj_uint8_t)(((c[2] & 0x03)<<6) | (c[3] & 0x3F));
}
pj_assert(j < *out_len);