Commit 287ca6ec authored by Geoff Simmons's avatar Geoff Simmons

first implementation of base64_decode()

parent edca76e2
......@@ -26,10 +26,11 @@
*
*/
#include <stdio.h>
#include <errno.h>
#include "vmod_convert.h"
#include "vrt.h"
#include "vas.h"
struct b64_state_s {
......@@ -59,6 +60,21 @@ alpha_init(struct b64_alphabet *alpha)
alpha->i64[alpha->padding] = 0;
}
static inline int
decode3(char *restrict *restrict dest, char *restrict const buf,
const size_t maxlen, unsigned u)
{
char *d = *dest;
for (int i = 0; i < 3; i++) {
if (d == buf + maxlen)
return -1;
*d++ = (u >> 16) & 0xff;
u <<= 8;
}
*dest += d - *dest;
return 1;
}
void
base64_init(void)
{
......@@ -160,3 +176,46 @@ base64_encode(const enum encoding enc, char *restrict const buf,
assert(outlen > 0);
return p - buf;
}
ssize_t
base64_decode(const enum encoding dec, char *restrict const buf,
const size_t maxlen, const char *restrict const p, va_list ap)
{
struct b64_alphabet *alpha = &b64_alphabet[dec];
const char *s;
char *dest = buf;
unsigned u = 0;
int n;
AN(buf);
for (s = p; s != vrt_magic_string_end; s = va_arg(ap, const char *)) {
if (s == NULL)
continue;
while (*s) {
for (n = 0; n < 4; n++) {
char b = alpha->i64[(unsigned) *s++];
if (b < 0) {
errno = EINVAL;
return -1;
}
u <<= 6;
u |= (unsigned) b;
if (!*s)
break;
}
if (n == 4)
if (decode3(&dest, buf, maxlen, u) < 0) {
errno = ENOMEM;
return -1;
}
}
}
if (n != 4)
if (decode3(&dest, buf, maxlen, u) < 0) {
errno = ENOMEM;
return -1;
}
return dest - buf;
}
......@@ -35,6 +35,15 @@ varnish v1 -vcl+backend {
set resp.http.b64urlnopadxcode =
convert.transcode(IDENTITY, BASE64URLNOPAD,
req.url + "Hello world" + req.url);
set resp.http.dec = convert.encode(IDENTITY,
convert.decode(BASE64, "L0hlbGxvIHdvcmxkLw=="));
set resp.http.dec2
= convert.encode(IDENTITY,
convert.decode(BASE64,
"VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw=="
));
}
} -start
......@@ -47,6 +56,8 @@ client c1 {
expect resp.http.b64xcode == "L0hlbGxvIHdvcmxkLw=="
expect resp.http.b64urlxcode == "L0hlbGxvIHdvcmxkLw=="
expect resp.http.b64urlnopadxcode == "L0hlbGxvIHdvcmxkLw"
expect resp.http.dec == "/Hello world/"
expect resp.http.dec2 == "The quick brown fox jumps over the lazy dog"
}
client c1 -run
......@@ -116,6 +116,10 @@ decode(const enum encoding dec, char *restrict const buf,
switch(dec) {
case IDENTITY:
return id_decode(dec, buf, maxlen, p, ap);
case BASE64:
case BASE64URL:
case BASE64URLNOPAD:
return base64_decode(dec, buf, maxlen, p, ap);
case HEX:
return hex_decode(dec, buf, maxlen, p, ap);
default:
......@@ -206,7 +210,8 @@ vmod_encode(VRT_CTX, VCL_ENUM encs, VCL_BLOB b) {
ssize_t len;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(b);
if (b == NULL)
return NULL;
if (wb_create(ctx->ws, &wb) == NULL)
return NULL;
......
......@@ -107,6 +107,7 @@ decode_f id_decode;
/* base64.c */
void base64_init(void);
encode_f base64_encode;
decode_f base64_decode;
/* hex.c */
encode_f hex_encode;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment