Preparing for vmod_digest, could I please have this integrated? #ifdef TEST_DRIVER block also contains more test cases
Thanks, Nils
Index: lib/libvarnishapi/base64.c =================================================================== --- lib/libvarnishapi/base64.c (revision 5288) +++ lib/libvarnishapi/base64.c (working copy) @@ -1,5 +1,18 @@ /* + * Utility functions for base64 encoding / decoding + * according to http://www.faqs.org/rfcs/rfc1113.html + * section 4.3.2.4 + * + * Limits: + * + * - As the functions are working on C strings, they will never encode '\0' + * - '*' (not encrypted) is unimplemented + * - Encoding line width limitation not implemented, the base64 encoded + * string will not be split up into multiple lines + * - Decoding of multi line input not implemented + * * Written by Poul-Henning Kamp <[email protected]> + * and Nils Goroll <[email protected]> * * This file is in the public domain. */ @@ -30,7 +43,57 @@ i64['='] = 0; } +/* + * yes, this is an independend implementation based upon RFC1113 only + * + */ int +base64_encode(char *e, unsigned elen, const char *s) +{ + char c; + int b; + + while (*s) { + if (elen < 4) + return (-1); + + for (b = 0; b < 3; b++) { + if (!s[b]) + break; + switch (b) { + case 0: + e[0] = b64[ (s[0] & 0xfc) >> 2]; + c = (s[0] & 0x3) << 4; + break; + case 1: + e[1] = b64[ c | ((s[1] & 0xf0) >> 4) ]; + c = (s[1] & 0xf) << 2; + break; + case 2: + e[2] = b64[ c | ((s[2] & 0xc0) >> 6) ]; + e[3] = b64[ s[2] & 0x3f ]; + } + } + switch (b) { + case 1: + e[1] = b64[ c ]; + e[2] = '='; + e[3] = '='; + break; + case 2: + e[2] = b64[ c ]; + e[3] = '='; + } + + elen -= 4; + e += 4; + s += 3; + } + *e='\0'; + return (0); +} + +int base64_decode(char *d, unsigned dlen, const char *s) { unsigned u, v, l; @@ -38,6 +101,7 @@ u = 0; l = 0; + while (*s) { for (v = 0; v < 4; v++) { if (!*s) @@ -62,29 +126,89 @@ } #ifdef TEST_DRIVER + +/* gcc -DTEST_DRIVER -I ../.. -I ../../include base64.c */ + #include <stdio.h> -const char *test1 = -"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz" -"IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg" -"dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu" -"dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo" -"ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="; +#define MAX_PRINTABLE 5 +#define MAX_TEST 6 +const char *test[MAX_TEST+1] = { + "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz" + "IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg" + "dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu" + "dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo" + "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=", /* 0 */ + "", /* 1 */ + /* all following tests encoded using GNU coreutils base64 */ + "YQ==", /* 2: "a" */ + "YWI=", /* 3: "ab" */ + "YWJj", /* 4: "abc" */ + "UGhrIGFuZCBWYXJuaXNoIHNob3VsZCByZWFsbHkgYmUgYXdhcmRlZCBhIHByaXplIGZvciBwcm90" + "ZWN0aW5nIG91ciBlbnZpcm9ubWVudCBieQpzaWduaWZpY2FudGx5IGxvd2VyaW5nIHRoZSBDTzIg" + "Zm9vdHByaW50IC8gZW5lcmd5IGNvbnN1bXB0aW9uIGJ5IHRvZGF5J3MgaW50ZXJuZXQKaW5kdXN0" + "cnkuIFRoZSBvbmx5IHF1ZXN0aW9uIGlzOiBEb2VzIHN1Y2ggYSBwcml6ZSBleGlzdD8K", /* 5 */ + /* + * 6: just some random data from: + * export LC_CTYPE=C + * dd if=/dev/random bs=256 count=1 | tr '\000' '0' | base64 + */ + "qZzhtC90adeYmJSbUUIXti2e6ob7Ru+QeVl9UiiqM9xtsRFh6gnWIFGDCksSmhZ74FkIPj34UawD" + "U7Db/5cWWMclJf+B55jmttozMvDW9IumypB/XjMr1W9e9gyiOOoRc1snjIGhyEdiRwvsOl2V0mX0" + "7e7StefOtImNz80gIWtGxq+e5KKW5GiJmVamla2zGNj2Sdvo1LV1CGOh3PhwGwJwmHOn9R1/zZ5x" + "XWosmz90Kp5RLDbsdDmc/jmJvGzZkE66p0554Xl4rFdu7jSWEqoQKGYboCa8YDAGzKhB0C+xth/J" + "F9T42OINv9VXkIjB0Vs+0geY3GifRqbjFPmk" +}; + int main(int argc, char **argv) { - int i; - char buf[BUFSIZ]; - unsigned l; + int i; + char buf1[BUFSIZ]; + char buf2[BUFSIZ]; + int l1, l2; + (void)argc; (void)argv; base64_init(); - l = sizeof buf; - base64_decode(buf, &l, test1); - printf("%s\n", buf); + + + for (i = 0; i <= MAX_TEST; i++) { + printf("\nTest %d:\n-------\n", i); + if (base64_decode(buf1, sizeof(buf1), test[i])) { + fprintf(stderr, "decode(test[%d]) failed\n", i); + return (1); + } + l1 = base64_decode_l(strlen(test[i])); + l2 = strlen(buf1) + 1; + printf("decode length estimated: %d, actual %d\n", l1, l2); + + if (i <= MAX_PRINTABLE) + printf("%s\n", buf1); + + if (base64_encode(buf2, sizeof(buf2), buf1)) { + fprintf(stderr, "encode(test[%d]) failed\n", i); + return (1); + } + + l1 = base64_encode_l(strlen(buf1)); + l2 = strlen(buf2) + 1; + printf("encode length estimated: %d, actual %d\n", l1, l2); + + printf("%s\n", test[i]); + printf("%s\n", buf2); + if (strcmp(test[i], buf2) != 0) { + fprintf(stderr, "encode(decode(test[%d])) != test[%d]\n", i, i); + return (1); + } + } return (0); } + +#undef MAX_PRINTABLE +#undef MAX_TEST + #endif Index: include/varnishapi.h =================================================================== --- include/varnishapi.h (revision 5288) +++ include/varnishapi.h (working copy) @@ -262,6 +262,11 @@ /* base64.c */ void base64_init(void); +int base64_encode(char *e, unsigned elen, const char *s); int base64_decode(char *d, unsigned dlen, const char *s); +/* safe estimate of length of de/encoded string including terminal NULL */ +#define base64_decode_l(l) ((l * 3 / 4) + 1) +#define base64_encode_l(l) (((((l * 4 / 3) + 3) / 4) * 4) + 1) + #endif
_______________________________________________ varnish-dev mailing list [email protected] http://lists.varnish-cache.org/mailman/listinfo/varnish-dev
