Commit c92c30ed authored by Steve Holme's avatar Steve Holme
Browse files

base64: Extended validation to look for invalid characters

Extended the basic validation in commit e17c1b25 to return a
failure when invalid base64 characters are included.
parent 4d10f486
Loading
Loading
Loading
Loading
+44 −16
Original line number Original line Diff line number Diff line
@@ -40,22 +40,32 @@
static const char table64[]=
static const char table64[]=
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";


static void decodeQuantum(unsigned char *dest, const char *src)
static size_t decodeQuantum(unsigned char *dest, const char *src)
{
{
  size_t padding = 0;
  const char *s, *p;
  const char *s, *p;
  unsigned long i, v, x = 0;
  unsigned long i, v, x = 0;


  for(i = 0, s = src; i < 4; i++, s++) {
  for(i = 0, s = src; i < 4; i++, s++) {
    v = 0;
    v = 0;

    if(*s == '=') {
      x = (x << 6);
      padding++;
    }
    else {
      p = table64;
      p = table64;

      while(*p && (*p != *s)) {
      while(*p && (*p != *s)) {
        v++;
        v++;
        p++;
        p++;
      }
      }

      if(*p == *s)
      if(*p == *s)
        x = (x << 6) + v;
        x = (x << 6) + v;
    else if(*s == '=')
      else
      x = (x << 6);
        return 0;
    }
  }
  }


  dest[2] = curlx_ultouc(x & 0xFFUL);
  dest[2] = curlx_ultouc(x & 0xFFUL);
@@ -63,6 +73,8 @@ static void decodeQuantum(unsigned char *dest, const char *src)
  dest[1] = curlx_ultouc(x & 0xFFUL);
  dest[1] = curlx_ultouc(x & 0xFFUL);
  x >>= 8;
  x >>= 8;
  dest[0] = curlx_ultouc(x & 0xFFUL);
  dest[0] = curlx_ultouc(x & 0xFFUL);

  return 3 - padding;
}
}


/*
/*
@@ -86,9 +98,11 @@ CURLcode Curl_base64_decode(const char *src,
  size_t length = 0;
  size_t length = 0;
  size_t equalsTerm = 0;
  size_t equalsTerm = 0;
  size_t i;
  size_t i;
  size_t result;
  size_t numQuantums;
  size_t numQuantums;
  unsigned char lastQuantum[3];
  unsigned char lastQuantum[3];
  size_t rawlen = 0;
  size_t rawlen = 0;
  unsigned char *pos;
  unsigned char *newstr;
  unsigned char *newstr;


  *outptr = NULL;
  *outptr = NULL;
@@ -125,24 +139,38 @@ CURLcode Curl_base64_decode(const char *src,
  if(!newstr)
  if(!newstr)
    return CURLE_OUT_OF_MEMORY;
    return CURLE_OUT_OF_MEMORY;


  *outptr = newstr;
  pos = newstr;


  /* Decode all but the last quantum (which may not decode to a
  /* Decode all but the last quantum (which may not decode to a
  multiple of 3 bytes) */
  multiple of 3 bytes) */
  for(i = 0; i < numQuantums - 1; i++) {
  for(i = 0; i < numQuantums - 1; i++) {
    decodeQuantum(newstr, src);
    result = decodeQuantum(pos, src);
    newstr += 3; src += 4;
    if(!result) {
      Curl_safefree(newstr);

      return CURLE_BAD_CONTENT_ENCODING;
    }

    pos += result;
    src += 4;
  }
  }


  /* Decode the last quantum */
  /* Decode the last quantum */
  decodeQuantum(lastQuantum, src);
  result = decodeQuantum(lastQuantum, src);
  if(!result) {
    Curl_safefree(newstr);

    return CURLE_BAD_CONTENT_ENCODING;
  }

  for(i = 0; i < 3 - equalsTerm; i++)
  for(i = 0; i < 3 - equalsTerm; i++)
    newstr[i] = lastQuantum[i];
    pos[i] = lastQuantum[i];


  /* Zero terminate */
  /* Zero terminate */
  newstr[i] = '\0';
  pos[i] = '\0';


  /* Return the size of decoded data */
  /* Return the decoded data */
  *outptr = newstr;
  *outlen = rawlen;
  *outlen = rawlen;


  return CURLE_OK;
  return CURLE_OK;
+8 −9
Original line number Original line Diff line number Diff line
@@ -5,7 +5,7 @@
 *                            | (__| |_| |  _ <| |___
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *                             \___|\___/|_| \_\_____|
 *
 *
 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 *
 * This software is licensed as described in the file COPYING, which
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * you should have received as part of this distribution. The terms
@@ -128,13 +128,12 @@ fail_unless(rc == CURLE_BAD_CONTENT_ENCODING, "return code should be CURLE_BAD_C
fail_unless(size == 0, "size should be 0");
fail_unless(size == 0, "size should be 0");
fail_if(decoded, "returned pointer should be NULL");
fail_if(decoded, "returned pointer should be NULL");


/* this is garbage input that libcurl decodes as far as possible */
/* This is garbage input as it contains an illegal base64 character */
size = 0;
size = 1; /* not zero */
decoded = NULL;
decoded = &anychar; /* not NULL */
rc = Curl_base64_decode("a\x1f==", &decoded, &size);
rc = Curl_base64_decode("a\x1f==", &decoded, &size);
fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
fail_unless(rc == CURLE_BAD_CONTENT_ENCODING, "return code should be CURLE_BAD_CONTENT_ENCODING");
fail_unless(size == 1, "size should be 1");
fail_unless(size == 0, "size should be 0");
fail_if(!decoded, "returned pointer should not be NULL");
fail_if(decoded, "returned pointer should be NULL");
Curl_safefree(decoded);


UNITTEST_STOP
UNITTEST_STOP