/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set expandtab shiftwidth=4 tabstop=4: */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "modp_burl.h"
#include "minunit.h"
/**
* Test empty input to encode and decode
*/
static char* testUrlEmpty()
{
int d;
char buf[1000];
buf[0] = 1;
d = modp_burl_encode(buf, "", 0);
mu_assert_int_equals(d, 0);
mu_assert(buf[0] == 0);
buf[0] = 1;
d = modp_burl_decode(buf, "", 0);
mu_assert_int_equals(d, 0);
mu_assert(buf[0] == 0);
return 0;
}
/**
* test space <--> plus conversion
*/
static char* testUrlSpaces()
{
size_t d = 0;
char buf[1000];
const char* input = " ";
const char* output = "+++";
d = modp_burl_encode(buf, input, strlen(input));
mu_assert_int_equals(d, strlen(output));
mu_assert_str_equals(buf, output);
d = modp_burl_decode(buf, output, strlen(output));
mu_assert_int_equals(d, strlen(input));
mu_assert_str_equals(buf, input);
return 0;
}
/**
* Test charactes that should be unchanged
*/
static char* testUrlUntouched()
{
const char* lower = "abcdefghijklmnopqrstuvwxyz";
const char* upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char* digits = "0123456789";
const char* special = ".-_";
char buf[1000];
size_t d = 0;
memset(buf, 0, sizeof(buf));
d = modp_burl_encode(buf, lower, strlen(lower));
mu_assert_int_equals(d, strlen(lower));
mu_assert_str_equals(buf, lower);
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, lower, strlen(lower));
mu_assert_int_equals(d, strlen(lower));
mu_assert_str_equals(buf, lower);
memset(buf, 0, sizeof(buf));
d = modp_burl_encode(buf, upper, strlen(upper));
mu_assert_int_equals(d, strlen(upper));
mu_assert_str_equals(buf, upper);
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, upper, strlen(upper));
mu_assert_int_equals(d, strlen(upper));
mu_assert_str_equals(buf, upper);
memset(buf, 0, sizeof(buf));
d = modp_burl_encode(buf, digits, strlen(digits));
mu_assert_int_equals(d, strlen(digits));
mu_assert_str_equals(buf, digits);
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, digits, strlen(digits));
mu_assert_int_equals(d, strlen(digits));
mu_assert_str_equals(buf, digits);
memset(buf, 0, sizeof(buf));
d = modp_burl_encode(buf, special, strlen(special));
mu_assert_int_equals(d, strlen(special));
mu_assert_str_equals(buf, special);
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, special, strlen(special));
mu_assert_int_equals(d, strlen(special));
mu_assert_str_equals(buf, special);
return 0;
}
/**
* Test charactes that should be unchanged
*/
static char* testUrlMinUntouched()
{
const char* lower = "abcdefghijklmnopqrstuvwxyz";
const char* upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char* digits = "0123456789";
const char* special = ".-_";
const char* extra = "~!$()*,;:@/?";
char buf[1000];
size_t d = 0;
memset(buf, 0, sizeof(buf));
d = modp_burl_min_encode(buf, lower, strlen(lower));
mu_assert_int_equals(d, strlen(lower));
mu_assert_str_equals(buf, lower);
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, lower, strlen(lower));
mu_assert_int_equals(d, strlen(lower));
mu_assert_str_equals(buf, lower);
memset(buf, 0, sizeof(buf));
d = modp_burl_min_encode(buf, upper, strlen(upper));
mu_assert_int_equals(d, strlen(upper));
mu_assert_str_equals(buf, upper);
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, upper, strlen(upper));
mu_assert_int_equals(d, strlen(upper));
mu_assert_str_equals(buf, upper);
memset(buf, 0, sizeof(buf));
d = modp_burl_min_encode(buf, digits, strlen(digits));
mu_assert_int_equals(d, strlen(digits));
mu_assert_str_equals(buf, digits);
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, digits, strlen(digits));
mu_assert_int_equals(d, strlen(digits));
mu_assert_str_equals(buf, digits);
memset(buf, 0, sizeof(buf));
d = modp_burl_min_encode(buf, special, strlen(special));
mu_assert_int_equals(d, strlen(special));
mu_assert_str_equals(buf, special);
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, special, strlen(special));
mu_assert_int_equals(d, strlen(special));
mu_assert_str_equals(buf, special);
memset(buf, 0, sizeof(buf));
d = modp_burl_min_encode(buf, extra, strlen(extra));
mu_assert_int_equals(d, strlen(extra));
mu_assert_str_equals(buf, extra);
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, extra, strlen(extra));
mu_assert_int_equals(d, strlen(extra));
mu_assert_str_equals(buf, extra);
return 0;
}
/** \brief make sure min encoding actually does hex encoding
*
*/
static char* testUrlMinEncodeHex()
{
char buf[1000];
size_t d = 0;
memset(buf, 0, sizeof(buf));
const char* str1 = "a b";
d = modp_burl_min_encode(buf, str1, strlen(str1));
mu_assert_int_equals(3, d);
mu_assert_str_equals("a+b", buf);
memset(buf, 0, sizeof(buf));
const char* str2 = "ab\n";
d = modp_burl_min_encode(buf, str2, strlen(str2));
mu_assert_int_equals(5, d);
mu_assert_str_equals("ab%0A", buf);
return 0;
}
static char* testUrlDecodeHexBad()
{
const char* bad1 = "%0X"; // bad trailing char
const char* bad2 = "%X0"; // bad leading char
const char* bad3 = "%XX"; // bad chars
const char* bad4 = "%2"; // not enough room, good char
const char* bad5 = "%X"; // not enought room, bad char
const char* bad6 = "%"; // test oddball
const char* bad7 = "AA%"; // test end of line
char bad8[4]; // %XX where X is high bit (test sign char vs. uint8_t*)
bad8[0] = '%';
bad8[1] = 0x81;
bad8[2] = 0x82;
bad8[3] = 0;
size_t d = 0;
char buf[1000];
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, bad1, strlen(bad1));
mu_assert_int_equals(d, strlen(bad1));
mu_assert_str_equals(buf, bad1);
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, bad2, strlen(bad2));
mu_assert_int_equals(d, strlen(bad2));
mu_assert_str_equals(bad2, buf);
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, bad3, strlen(bad3));
mu_assert_int_equals(d, strlen(bad3));
mu_assert_str_equals(buf, bad3);
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, bad4, strlen(bad4));
mu_assert_int_equals(d, strlen(bad4));
mu_assert_str_equals(buf, bad4);
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, bad5, strlen(bad5));
mu_assert_int_equals(d, strlen(bad5));
mu_assert_str_equals(buf, bad5);
memset(buf, 0, sizeof(buf));
d= modp_burl_decode(buf, bad6, strlen(bad6));
mu_assert_int_equals(d, strlen(bad6));
mu_assert_str_equals(buf, bad6);
memset(buf, 0, sizeof(buf));
d= modp_burl_decode(buf, bad7, strlen(bad7));
mu_assert_int_equals(d, strlen(bad7));
mu_assert_str_equals(buf, bad7);
memset(buf, 0, sizeof(buf));
d = modp_burl_decode(buf, bad8, strlen(bad8));
mu_assert_int_equals(d, strlen(bad8));
mu_assert_str_equals(buf, bad8);
return 0;
return 0;
}
static char* testUrlDecodeHex()
{
int d; // size of output
int i, j; // loops
int k = 0; // position in inputbuf;
char inputbuf[3*256+1];
char output[257];
char msg[1000];
// make input string contain every possible "%XX"
static const char* hexdigits1 = "0123456789ABCDEF";
memset(inputbuf, 0, sizeof(inputbuf));
memset(output, 1, sizeof(output));
k = 0;
for (i = 0; i < 16; ++i) {
for (j = 0; j < 16; ++j) {
inputbuf[k++] = '%';
inputbuf[k++] = hexdigits1[i];
inputbuf[k++] = hexdigits1[j];
}
}
d = modp_burl_decode(output, inputbuf, sizeof(inputbuf)-1);
mu_assert_int_equals(d, 256);
for (i = 0; i < 256; ++i) {
sprintf(msg, "Loop at %d", i);
mu_assert_int_equals_msg(msg, i, (unsigned char) output[i]);
}
// make input string contain every possible "%XX"
static const char* hexdigits2 = "0123456789abcdef";
memset(inputbuf, 0, sizeof(inputbuf));
memset(output, 1, sizeof(output));
k = 0;
for (i = 0; i < 16; ++i) {
for (j = 0; j < 16; ++j) {
inputbuf[k++] = '%';
inputbuf[k++] = hexdigits2[i];
inputbuf[k++] = hexdigits2[j];
}
}
d = modp_burl_decode(output, inputbuf, sizeof(inputbuf)-1);
mu_assert_int_equals(256, d);
for (i = 0; i < 256; ++i) {
sprintf(msg, "Loop at %d", i);
mu_assert_int_equals_msg(msg, i, (unsigned char)output[i]);
}
return 0;
}
/**
* test hex encoding.. to be done after hex decoding
* is tested.
*/
static char* testHexEncoding()
{
int i = 0;
int d = 0;
char msg[1000];
char input[257];
memset(input, 0, sizeof(input));
char output[257*3];
memset(output, 0, sizeof(output));
char buf[1000];
memset(buf, 0, sizeof(buf));
d = modp_burl_encode(output, input, 256);
d = modp_burl_decode(buf, output, d);
mu_assert_int_equals(256, d);
for (i= 0; i < 256; ++i) {
sprintf(msg, "Loop at %d failed", i);
mu_assert_int_equals_msg(msg, input[i], buf[i]);
}
return 0;
}
static char* testEncodeStrlen()
{
char ibuf[100];
char obuf[100];
memset(ibuf, 0, sizeof(ibuf));
memset(obuf, 0, sizeof(obuf));
// Empty. should be 0
ibuf[0] = 0;
mu_assert_int_equals(strlen(ibuf), (size_t) modp_burl_encode_strlen(ibuf, strlen(ibuf)));
// Plain, should be same size
strcpy(ibuf, "abcdefg");
mu_assert_int_equals(strlen(ibuf), (size_t) modp_burl_encode_strlen(ibuf, strlen(ibuf)));
// Plain and spaces, should be same size
strcpy(ibuf, "a b c d e f g");
mu_assert_int_equals(strlen(ibuf), (size_t) modp_burl_encode_strlen(ibuf, strlen(ibuf)));
// one bad char, adds two bytes
strcpy(ibuf, "abcdefg\n");
mu_assert_int_equals(strlen(ibuf)+2, (size_t) modp_burl_encode_strlen(ibuf, strlen(ibuf)));
// 2 bad chars, adds 4 bytes
strcpy(ibuf, "\nabcdefg\n");
mu_assert_int_equals(strlen(ibuf)+4, (size_t) modp_burl_encode_strlen(ibuf, strlen(ibuf)));
return 0;
}
/** \brief test "modp_burl_min_encode_strlen"
*
*/
static char* testEncodeMinStrlen()
{
char ibuf[100];
char obuf[100];
memset(ibuf, 0, sizeof(ibuf));
memset(obuf, 0, sizeof(obuf));
// Empty. should be 0
ibuf[0] = 0;
mu_assert_int_equals(strlen(ibuf), (size_t) modp_burl_min_encode_strlen(ibuf, strlen(ibuf)));
// Plain, should be same size
strcpy(ibuf, "abcdefg");
mu_assert_int_equals(strlen(ibuf), (size_t) modp_burl_min_encode_strlen(ibuf, strlen(ibuf)));
// Plain and spaces, should be same size
strcpy(ibuf, "a b c d e f g");
mu_assert_int_equals(strlen(ibuf), (size_t) modp_burl_min_encode_strlen(ibuf, strlen(ibuf)));
// one bad char, adds two bytes
strcpy(ibuf, "abcdefg\n");
mu_assert_int_equals(strlen(ibuf)+2, (size_t) modp_burl_min_encode_strlen(ibuf, strlen(ibuf)));
// 2 bad chars, adds 4 bytes
strcpy(ibuf, "\nabcdefg\n");
mu_assert_int_equals(strlen(ibuf)+4, (size_t) modp_burl_min_encode_strlen(ibuf, strlen(ibuf)));
return 0;
}
static char* all_tests()
{
mu_run_test(testUrlUntouched);
mu_run_test(testUrlEmpty);
mu_run_test(testUrlSpaces);
mu_run_test(testUrlDecodeHex);
mu_run_test(testUrlDecodeHexBad);
mu_run_test(testHexEncoding);
mu_run_test(testEncodeStrlen);
mu_run_test(testUrlMinUntouched);
mu_run_test(testUrlMinEncodeHex);
mu_run_test(testEncodeMinStrlen);
return 0;
}
UNITTESTS
syntax highlighted by Code2HTML, v. 0.9.1