From c64411a38a25e696edb33e49f8917012d0cd4cba Mon Sep 17 00:00:00 2001 From: Bo Borgerson Date: Wed, 30 Apr 2008 17:40:38 -0400 Subject: base64 module: adjust API so it's compatible with gnulib's * gl/lib/base64.c (base64_decode_ctx): If no context structure was passed in, treat newlines as garbage (this is the historical behavior). Formerly base64_decode. (base64_decode_alloc_ctx): Formerly base64_decode_alloc. * gl/lib/base64.h (base64_decode): Macro for four-argument calls. (base64_decode_alloc): Likewise. * src/base64.c (do_decode): Call base64_decode_ctx instead of base64_decode. Signed-off-by: Bo Borgerson --- gl/lib/base64.c | 45 +++++++++++++++++++++++++++++++-------------- gl/lib/base64.h | 19 +++++++++++++------ src/base64.c | 2 +- 3 files changed, 45 insertions(+), 21 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 */ diff --git a/src/base64.c b/src/base64.c index aa2fc8fd6..983b8cb88 100644 --- a/src/base64.c +++ b/src/base64.c @@ -223,7 +223,7 @@ do_decode (FILE *in, FILE *out, bool ignore_garbage) if (k == 1 && ctx.i == 0) break; n = BLOCKSIZE; - ok = base64_decode (&ctx, inbuf, (k == 0 ? sum : 0), outbuf, &n); + ok = base64_decode_ctx (&ctx, inbuf, (k == 0 ? sum : 0), outbuf, &n); if (fwrite (outbuf, 1, n, out) < n) error (EXIT_FAILURE, errno, _("write error")); -- cgit v1.2.3-70-g09d2