X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/011e0b894ce9b8ccadc797860ba126dee957b0fe..422a9507e9cbb817d6c2b20a3a8b7d539e16e688:/lib/test.c diff --git a/lib/test.c b/lib/test.c index e8e550f..27651ec 100644 --- a/lib/test.c +++ b/lib/test.c @@ -34,8 +34,10 @@ #include #include #include +#include +#include +#include -#include "utf8.h" #include "mem.h" #include "log.h" #include "vector.h" @@ -57,6 +59,10 @@ #include "printf.h" #include "basen.h" #include "split.h" +#include "configuration.h" +#include "addr.h" +#include "base64.h" +#include "url.h" static int tests, errors; static int fail_first; @@ -448,30 +454,109 @@ static void test_mime(void) { check_string(mime_qp("x =\r\ny"), "x y"); check_string(mime_qp("x = \r\ny"), "x y"); + check_string(mime_to_qp(""), ""); + check_string(mime_to_qp("foobar\n"), "foobar\n"); + check_string(mime_to_qp("foobar \n"), "foobar=20\n"); + check_string(mime_to_qp("foobar\t\n"), "foobar=09\n"); + check_string(mime_to_qp("foobar \t \n"), "foobar=20=09=20\n"); + check_string(mime_to_qp(" foo=bar"), " foo=3Dbar\n"); + check_string(mime_to_qp("copyright \xC2\xA9"), "copyright =C2=A9\n"); + check_string(mime_to_qp("foo\nbar\nbaz\n"), "foo\nbar\nbaz\n"); + check_string(mime_to_qp("wibble wobble wibble wobble wibble wobble wibble wobble wibble wobble wibble"), "wibble wobble wibble wobble wibble wobble wibble wobble wibble wobble wibb=\nle\n"); + /* from RFC2045 */ check_string(mime_qp("Now's the time =\r\n" "for all folk to come=\r\n" " to the aid of their country."), "Now's the time for all folk to come to the aid of their country."); - check_string(mime_base64(""), ""); - check_string(mime_base64("BBBB"), "\x04\x10\x41"); - check_string(mime_base64("////"), "\xFF\xFF\xFF"); - check_string(mime_base64("//BB"), "\xFF\xF0\x41"); - check_string(mime_base64("BBBB//BB////"), - "\x04\x10\x41" "\xFF\xF0\x41" "\xFF\xFF\xFF"); - check_string(mime_base64("B B B B / / B B / / / /"), - "\x04\x10\x41" "\xFF\xF0\x41" "\xFF\xFF\xFF"); - check_string(mime_base64("B\r\nBBB.// B-B//~//"), +#define check_base64(encoded, decoded) do { \ + check_string(mime_base64(encoded, 0), decoded); \ + check_string(mime_to_base64((const uint8_t *)decoded, \ + (sizeof decoded) - 1), \ + encoded); \ + } while(0) + + + check_base64("", ""); + check_base64("BBBB", "\x04\x10\x41"); + check_base64("////", "\xFF\xFF\xFF"); + check_base64("//BB", "\xFF\xF0\x41"); + check_base64("BBBB//BB////", + "\x04\x10\x41" "\xFF\xF0\x41" "\xFF\xFF\xFF"); + check_base64("BBBBBA==", + "\x04\x10\x41" "\x04"); + check_base64("BBBBBBA=", + "\x04\x10\x41" "\x04\x10"); + + /* Check that decoding handles various kinds of rubbish OK */ + check_string(mime_base64("B B B B / / B B / / / /", 0), + "\x04\x10\x41" "\xFF\xF0\x41" "\xFF\xFF\xFF"); + check_string(mime_base64("B\r\nBBB.// B-B//~//", 0), "\x04\x10\x41" "\xFF\xF0\x41" "\xFF\xFF\xFF"); - check_string(mime_base64("BBBB="), - "\x04\x10\x41"); - check_string(mime_base64("BBBBx="), /* not actually valid base64 */ + check_string(mime_base64("BBBB BB==", 0), + "\x04\x10\x41" "\x04"); + check_string(mime_base64("BBBB BB = =", 0), + "\x04\x10\x41" "\x04"); + check_string(mime_base64("BBBB BBB=", 0), + "\x04\x10\x41" "\x04\x10"); + check_string(mime_base64("BBBB BBB = ", 0), + "\x04\x10\x41" "\x04\x10"); + check_string(mime_base64("BBBB=", 0), "\x04\x10\x41"); - check_string(mime_base64("BBBB BB=="), + check_string(mime_base64("BBBBBB==", 0), "\x04\x10\x41" "\x04"); - check_string(mime_base64("BBBB BBB="), + check_string(mime_base64("BBBBBBB=", 0), "\x04\x10\x41" "\x04\x10"); + /* Not actually valid base64 */ + check_string(mime_base64("BBBBx=", 0), + "\x04\x10\x41"); +} + +static void test_cookies(void) { + struct cookiedata cd[1]; + + fprintf(stderr, "test_cookies\n"); + + /* These are the examples from RFC2109 */ + insist(!parse_cookie("$Version=\"1\"; Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\"", cd)); + insist(!strcmp(cd->version, "1")); + insist(cd->ncookies = 1); + insist(find_cookie(cd, "Customer") == &cd->cookies[0]); + check_string(cd->cookies[0].value, "WILE_E_COYOTE"); + check_string(cd->cookies[0].path, "/acme"); + insist(cd->cookies[0].domain == 0); + insist(!parse_cookie("$Version=\"1\";\n" + "Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\";\n" + "Part_Number=\"Rocket_Launcher_0001\"; $Path=\"/acme\"", + cd)); + insist(cd->ncookies = 2); + insist(find_cookie(cd, "Customer") == &cd->cookies[0]); + insist(find_cookie(cd, "Part_Number") == &cd->cookies[1]); + check_string(cd->cookies[0].value, "WILE_E_COYOTE"); + check_string(cd->cookies[0].path, "/acme"); + insist(cd->cookies[0].domain == 0); + check_string(cd->cookies[1].value, "Rocket_Launcher_0001"); + check_string(cd->cookies[1].path, "/acme"); + insist(cd->cookies[1].domain == 0); + insist(!parse_cookie("$Version=\"1\";\n" + "Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\";\n" + "Part_Number=\"Rocket_Launcher_0001\"; $Path=\"/acme\";\n" + "Shipping=\"FedEx\"; $Path=\"/acme\"", + cd)); + insist(cd->ncookies = 3); + insist(find_cookie(cd, "Customer") == &cd->cookies[0]); + insist(find_cookie(cd, "Part_Number") == &cd->cookies[1]); + insist(find_cookie(cd, "Shipping") == &cd->cookies[2]); + check_string(cd->cookies[0].value, "WILE_E_COYOTE"); + check_string(cd->cookies[0].path, "/acme"); + insist(cd->cookies[0].domain == 0); + check_string(cd->cookies[1].value, "Rocket_Launcher_0001"); + check_string(cd->cookies[1].path, "/acme"); + insist(cd->cookies[1].domain == 0); + check_string(cd->cookies[2].value, "FedEx"); + check_string(cd->cookies[2].path, "/acme"); + insist(cd->cookies[2].domain == 0); } static void test_hex(void) { @@ -1279,6 +1364,77 @@ static void test_hash(void) { check_integer(hash_count(h), 0); } +static void test_addr(void) { + struct stringlist a; + const char *s[2]; + struct addrinfo *ai; + char *name; + const struct sockaddr_in *sin; + + static const struct addrinfo pref = { + AI_PASSIVE, + PF_INET, + SOCK_STREAM, + 0, + 0, + 0, + 0, + 0 + }; + + printf("test_addr\n"); + + a.n = 1; + a.s = (char **)s; + s[0] = "smtp"; + ai = get_address(&a, &pref, &name); + insist(ai != 0); + check_integer(ai->ai_family, PF_INET); + check_integer(ai->ai_socktype, SOCK_STREAM); + check_integer(ai->ai_protocol, IPPROTO_TCP); + check_integer(ai->ai_addrlen, sizeof(struct sockaddr_in)); + sin = (const struct sockaddr_in *)ai->ai_addr; + check_integer(sin->sin_family, AF_INET); + check_integer(sin->sin_addr.s_addr, 0); + check_integer(ntohs(sin->sin_port), 25); + check_string(name, "host * service smtp"); + + a.n = 2; + s[0] = "localhost"; + s[1] = "nntp"; + ai = get_address(&a, &pref, &name); + insist(ai != 0); + check_integer(ai->ai_family, PF_INET); + check_integer(ai->ai_socktype, SOCK_STREAM); + check_integer(ai->ai_protocol, IPPROTO_TCP); + check_integer(ai->ai_addrlen, sizeof(struct sockaddr_in)); + sin = (const struct sockaddr_in *)ai->ai_addr; + check_integer(sin->sin_family, AF_INET); + check_integer(ntohl(sin->sin_addr.s_addr), 0x7F000001); + check_integer(ntohs(sin->sin_port), 119); + check_string(name, "host localhost service nntp"); +} + +static void test_url(void) { + struct url p; + + printf("test_url\n"); + + insist(parse_url("http://www.example.com/example/path", &p) == 0); + check_string(p.scheme, "http"); + check_string(p.host, "www.example.com"); + insist(p.port == -1); + check_string(p.path, "/example/path"); + insist(p.query == 0); + + insist(parse_url("https://www.example.com:82/example%2fpath?+query+", &p) == 0); + check_string(p.scheme, "https"); + check_string(p.host, "www.example.com"); + insist(p.port == 82); + check_string(p.path, "/example/path"); + check_string(p.query, "+query+"); +} + int main(void) { mem_init(); fail_first = !!getenv("FAIL_FIRST"); @@ -1292,6 +1448,7 @@ int main(void) { insist('a' == 0x61); insist('z' == 0x7A); /* addr.c */ + test_addr(); /* asprintf.c */ /* authhash.c */ /* basen.c */ @@ -1314,6 +1471,7 @@ int main(void) { /* mem.c */ /* mime.c */ test_mime(); + test_cookies(); /* mixer.c */ /* plugin.c */ /* printf.c */ @@ -1343,6 +1501,7 @@ int main(void) { /* selection.c */ test_selection(); test_hash(); + test_url(); fprintf(stderr, "%d errors out of %d tests\n", errors, tests); return !!errors; }