Back to index

nagios-plugins  1.4.16
Defines | Functions | Variables
base64.c File Reference
#include <config.h>
#include "base64.h"
#include <stdlib.h>
#include <limits.h>
#include <string.h>

Go to the source code of this file.

Defines

#define B64(_)
#define uchar_in_range(c)   ((c) <= 255)
#define return_false

Functions

static unsigned char to_uchar (char ch)
void base64_encode (const char *restrict in, size_t inlen, char *restrict out, size_t outlen)
size_t base64_encode_alloc (const char *in, size_t inlen, char **out)
bool isbase64 (char ch)
void base64_decode_ctx_init (struct base64_decode_context *ctx)
static char * get_4 (struct base64_decode_context *ctx, char const *restrict *in, char const *restrict in_end, size_t *n_non_newline)
static bool decode_4 (char const *restrict in, size_t inlen, char *restrict *outp, size_t *outleft)
bool base64_decode_ctx (struct base64_decode_context *ctx, const char *restrict in, size_t inlen, char *restrict out, size_t *outlen)
bool base64_decode_alloc_ctx (struct base64_decode_context *ctx, const char *in, size_t inlen, char **out, size_t *outlen)

Variables

static const signed char b64 [0x100]

Define Documentation

#define B64 (   _)

Definition at line 156 of file base64.c.

#define return_false
Value:
do                                            \
    {                                           \
      *outp = out;                              \
      return false;                             \
    }                                           \
  while (false)

Definition at line 359 of file base64.c.

#define uchar_in_range (   c)    ((c) <= 255)

Definition at line 293 of file base64.c.


Function Documentation

bool base64_decode_alloc_ctx ( struct base64_decode_context ctx,
const char *  in,
size_t  inlen,
char **  out,
size_t *  outlen 
)

Definition at line 550 of file base64.c.

{
  /* 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.
     The exact size is 3 * inlen / 4, minus 1 if the input ends
     with "=" and minus another 1 if the input ends with "==".
     Dividing before multiplying avoids the possibility of overflow.  */
  size_t needlen = 3 * (inlen / 4) + 2;

  *out = malloc (needlen);
  if (!*out)
    return true;

  if (!base64_decode_ctx (ctx, in, inlen, *out, &needlen))
    {
      free (*out);
      *out = NULL;
      return false;
    }

  if (outlen)
    *outlen = needlen;

  return true;
}

Here is the call graph for this function:

bool base64_decode_ctx ( struct base64_decode_context ctx,
const char *restrict  in,
size_t  inlen,
char *restrict  out,
size_t *  outlen 
)

Definition at line 459 of file base64.c.

{
  size_t outleft = *outlen;
  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)
        {
          while (true)
            {
              /* Save a copy of outleft, in case we need to re-parse this
                 block of four bytes.  */
              outleft_save = outleft;
              if (!decode_4 (in, inlen, &out, &outleft))
                break;

              in += 4;
              inlen -= 4;
            }
        }

      if (inlen == 0 && !flush_ctx)
        break;

      /* Handle the common case of 72-byte wrapped lines.
         This also handles any other multiple-of-4-byte wrapping.  */
      if (inlen && *in == '\n' && ignore_newlines)
        {
          ++in;
          --inlen;
          continue;
        }

      /* Restore OUT and OUTLEFT.  */
      out -= outleft_save - outleft;
      outleft = outleft_save;

      {
        char const *in_end = in + 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 and not treating newlines as garbage.  */
        if (inlen == 0 || (inlen < 4 && !flush_ctx && ignore_newlines))
          {
            inlen = 0;
            break;
          }
        if (!decode_4 (non_nl, inlen, &out, &outleft))
          break;

        inlen = in_end - in;
      }
    }

  *outlen -= outleft;

  return inlen == 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 307 of file base64.c.

{
  ctx->i = 0;
}
void base64_encode ( const char *restrict  in,
size_t  inlen,
char *restrict  out,
size_t  outlen 
)

Definition at line 69 of file base64.c.

{
  static const char b64str[64] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

  while (inlen && outlen)
    {
      *out++ = b64str[(to_uchar (in[0]) >> 2) & 0x3f];
      if (!--outlen)
        break;
      *out++ = b64str[((to_uchar (in[0]) << 4)
                       + (--inlen ? to_uchar (in[1]) >> 4 : 0))
                      & 0x3f];
      if (!--outlen)
        break;
      *out++ =
        (inlen
         ? b64str[((to_uchar (in[1]) << 2)
                   + (--inlen ? to_uchar (in[2]) >> 6 : 0))
                  & 0x3f]
         : '=');
      if (!--outlen)
        break;
      *out++ = inlen ? b64str[to_uchar (in[2]) & 0x3f] : '=';
      if (!--outlen)
        break;
      if (inlen)
        inlen--;
      if (inlen)
        in += 3;
    }

  if (outlen)
    *out = '\0';
}

Here is the call graph for this function:

Here is the caller graph for this function:

size_t base64_encode_alloc ( const char *  in,
size_t  inlen,
char **  out 
)

Definition at line 116 of file base64.c.

{
  size_t outlen = 1 + BASE64_LENGTH (inlen);

  /* Check for overflow in outlen computation.
   *
   * If there is no overflow, outlen >= inlen.
   *
   * If the operation (inlen + 2) overflows then it yields at most +1, so
   * outlen is 0.
   *
   * If the multiplication overflows, we lose at least half of the
   * correct value, so the result is < ((inlen + 2) / 3) * 2, which is
   * less than (inlen + 2) * 0.66667, which is less than inlen as soon as
   * (inlen > 4).
   */
  if (inlen > outlen)
    {
      *out = NULL;
      return 0;
    }

  *out = malloc (outlen);
  if (!*out)
    return outlen;

  base64_encode (in, inlen, *out, outlen);

  return outlen - 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool decode_4 ( char const *restrict  in,
size_t  inlen,
char *restrict *  outp,
size_t *  outleft 
) [inline, static]

Definition at line 374 of file base64.c.

{
  char *out = *outp;
  if (inlen < 2)
    return false;

  if (!isbase64 (in[0]) || !isbase64 (in[1]))
    return false;

  if (*outleft)
    {
      *out++ = ((b64[to_uchar (in[0])] << 2)
                | (b64[to_uchar (in[1])] >> 4));
      --*outleft;
    }

  if (inlen == 2)
    return_false;

  if (in[2] == '=')
    {
      if (inlen != 4)
        return_false;

      if (in[3] != '=')
        return_false;
    }
  else
    {
      if (!isbase64 (in[2]))
        return_false;

      if (*outleft)
        {
          *out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0)
                    | (b64[to_uchar (in[2])] >> 2));
          --*outleft;
        }

      if (inlen == 3)
        return_false;

      if (in[3] == '=')
        {
          if (inlen != 4)
            return_false;
        }
      else
        {
          if (!isbase64 (in[3]))
            return_false;

          if (*outleft)
            {
              *out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0)
                        | b64[to_uchar (in[3])]);
              --*outleft;
            }
        }
    }

  *outp = out;
  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* get_4 ( struct base64_decode_context ctx,
char const *restrict *  in,
char const *restrict  in_end,
size_t *  n_non_newline 
) [inline, static]

Definition at line 320 of file base64.c.

{
  if (ctx->i == 4)
    ctx->i = 0;

  if (ctx->i == 0)
    {
      char const *t = *in;
      if (4 <= in_end - *in && memchr (t, '\n', 4) == NULL)
        {
          /* This is the common case: no newline.  */
          *in += 4;
          *n_non_newline = 4;
          return (char *) t;
        }
    }

  {
    /* Copy non-newline bytes into BUF.  */
    char const *p = *in;
    while (p < in_end)
      {
        char c = *p++;
        if (c != '\n')
          {
            ctx->buf[ctx->i++] = c;
            if (ctx->i == 4)
              break;
          }
      }

    *in = p;
    *n_non_newline = ctx->i;
    return ctx->buf;
  }
}

Here is the caller graph for this function:

bool isbase64 ( char  ch)

Definition at line 300 of file base64.c.

{
  return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)];
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned char to_uchar ( char  ch) [inline, static]

Definition at line 59 of file base64.c.

{
  return ch;
}

Here is the caller graph for this function:


Variable Documentation

const signed char b64[0x100] [static]

Definition at line 223 of file base64.c.