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

Reply via email to