diff options
Diffstat (limited to 'gl/lib')
-rw-r--r-- | gl/lib/base64.c | 45 | ||||
-rw-r--r-- | gl/lib/base64.h | 19 |
2 files changed, 44 insertions, 20 deletions
diff --git a/gl/lib/base64.c b/gl/lib/base64.c index 43f12c6b0..a33f10216 100644 --- a/gl/lib/base64.c +++ b/gl/lib/base64.c @@ -449,20 +449,32 @@ decode_4 (char const *restrict in, size_t inlen, Initially, CTX must have been initialized via base64_decode_ctx_init. Subsequent calls to this function must reuse whatever state is recorded in that buffer. It is necessary for when a quadruple of base64 input - bytes spans two input buffers. */ + bytes spans two input buffers. + + If CTX is NULL then newlines are treated as garbage and the input + buffer is processed as a unit. */ bool -base64_decode (struct base64_decode_context *ctx, - const char *restrict in, size_t inlen, - char *restrict out, size_t *outlen) +base64_decode_ctx (struct base64_decode_context *ctx, + const char *restrict in, size_t inlen, + char *restrict out, size_t *outlen) { size_t outleft = *outlen; - bool flush_ctx = inlen == 0; + bool ignore_newlines = ctx != NULL; + bool flush_ctx = false; + unsigned int ctx_i = 0; + + if (ignore_newlines) + { + ctx_i = ctx->i; + flush_ctx = inlen == 0; + } + while (true) { size_t outleft_save = outleft; - if (ctx->i == 0 && !flush_ctx) + if (ctx_i == 0 && !flush_ctx) { while (true) { @@ -482,7 +494,7 @@ base64_decode (struct base64_decode_context *ctx, /* Handle the common case of 72-byte wrapped lines. This also handles any other multiple-of-4-byte wrapping. */ - if (inlen && *in == '\n') + if (inlen && *in == '\n' && ignore_newlines) { ++in; --inlen; @@ -495,12 +507,17 @@ base64_decode (struct base64_decode_context *ctx, { char const *in_end = in + inlen; - char const *non_nl = get_4 (ctx, &in, in_end, &inlen); + char const *non_nl; + + if (ignore_newlines) + non_nl = get_4 (ctx, &in, in_end, &inlen); + else + non_nl = in; /* Might have nl in this case. */ /* If the input is empty or consists solely of newlines (0 non-newlines), then we're done. Likewise if there are fewer than 4 bytes when not - flushing context. */ - if (inlen == 0 || (inlen < 4 && !flush_ctx)) + flushing context and not treating newlines as garbage. */ + if (inlen == 0 || (inlen < 4 && !flush_ctx && ignore_newlines)) { inlen = 0; break; @@ -529,9 +546,9 @@ base64_decode (struct base64_decode_context *ctx, input was invalid, in which case *OUT is NULL and *OUTLEN is undefined. */ bool -base64_decode_alloc (struct base64_decode_context *ctx, - const char *in, size_t inlen, char **out, - size_t *outlen) +base64_decode_alloc_ctx (struct base64_decode_context *ctx, + const char *in, size_t inlen, char **out, + size_t *outlen) { /* This may allocate a few bytes too many, depending on input, but it's not worth the extra CPU time to compute the exact size. @@ -544,7 +561,7 @@ base64_decode_alloc (struct base64_decode_context *ctx, if (!*out) return true; - if (!base64_decode (ctx, in, inlen, *out, &needlen)) + if (!base64_decode_ctx (ctx, in, inlen, *out, &needlen)) { free (*out); *out = NULL; diff --git a/gl/lib/base64.h b/gl/lib/base64.h index ba436e02f..fa242c82d 100644 --- a/gl/lib/base64.h +++ b/gl/lib/base64.h @@ -42,12 +42,19 @@ extern void base64_encode (const char *restrict in, size_t inlen, extern size_t base64_encode_alloc (const char *in, size_t inlen, char **out); extern void base64_decode_ctx_init (struct base64_decode_context *ctx); -extern bool base64_decode (struct base64_decode_context *ctx, - const char *restrict in, size_t inlen, - char *restrict out, size_t *outlen); -extern bool base64_decode_alloc (struct base64_decode_context *ctx, - const char *in, size_t inlen, - char **out, size_t *outlen); +extern bool base64_decode_ctx (struct base64_decode_context *ctx, + const char *restrict in, size_t inlen, + char *restrict out, size_t *outlen); + +extern bool base64_decode_alloc_ctx (struct base64_decode_context *ctx, + const char *in, size_t inlen, + char **out, size_t *outlen); + +#define base64_decode(in, inlen, out, outlen) \ + base64_decode_ctx (NULL, in, inlen, out, outlen) + +#define base64_decode_alloc(in, inlen, out, outlen) \ + base64_decode_alloc_ctx (NULL, in, inlen, out, outlen) #endif /* BASE64_H */ |