X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/f4d091fbe1f4cc0a6a7c11c174eaca32402290ec..8d6cb5fdac4b2bab0922fe431e12d8f7cc02d723:/src/src/base64.c diff --git a/src/src/base64.c b/src/src/base64.c index f4c4f233b..29f9c77b0 100644 --- a/src/src/base64.c +++ b/src/src/base64.c @@ -5,7 +5,8 @@ /* Copyright (c) Tom Kistner 2004, 2015 */ /* License: GPL */ -/* Copyright (c) University of Cambridge 1995 - 2015 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ +/* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -38,7 +39,7 @@ ssize_t mime_decode_base64(FILE * in, FILE * out, uschar * boundary) { uschar ibuf[MIME_MAX_LINE_LENGTH], obuf[MIME_MAX_LINE_LENGTH]; -uschar *ipos, *opos; +uschar *opos; ssize_t len, size = 0; int bytestate = 0; @@ -52,7 +53,7 @@ while (Ufgets(ibuf, MIME_MAX_LINE_LENGTH, in) != NULL) ) break; - for (ipos = ibuf ; *ipos != '\r' && *ipos != '\n' && *ipos != 0; ++ipos) + for (uschar * ipos = ibuf ; *ipos != '\r' && *ipos != '\n' && *ipos; ++ipos) if (*ipos == '=') /* skip padding */ ++bytestate; @@ -100,21 +101,21 @@ return size; #endif /*WITH_CONTENT_SCAN*/ /************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* + ************************************************* + ************************************************* + ************************************************* + ************************************************* + ************************************************* + ************************************************* + ************************************************* + ************************************************* + ************************************************* + ************************************************* + ************************************************* + ************************************************* + ************************************************* + ************************************************* + *************************************************/ /************************************************* @@ -129,11 +130,12 @@ compact loop is messy and would probably run more slowly. Arguments: code points to the coded string, zero-terminated ptr where to put the pointer to the result, which is in - dynamic store, and zero-terminated + allocated store, and zero-terminated Returns: the number of bytes in the result, or -1 if the input was malformed +Whitespace in the input is ignored. A zero is added on to the end to make it easy in cases where the result is to be interpreted as text. This is not included in the count. */ @@ -149,40 +151,67 @@ static uschar dec64table[] = { }; int -b64decode(uschar *code, uschar **ptr) +b64decode(const uschar *code, uschar **ptr) { + int x, y; -uschar *result = store_get(3*(Ustrlen(code)/4) + 1); +uschar *result; -*ptr = result; +{ + int l = Ustrlen(code); + *ptr = result = store_get(1 + l/4 * 3 + l%4, is_tainted(code)); +} /* Each cycle of the loop handles a quantum of 4 input bytes. For the last quantum this may decode to 1, 2, or 3 output bytes. */ while ((x = *code++) != 0) { + if (isspace(x)) continue; + /* debug_printf("b64d: '%c'\n", x); */ + if (x > 127 || (x = dec64table[x]) == 255) return -1; - if ((y = *code++) == 0 || (y = dec64table[y]) == 255) + + while (isspace(y = *code++)) ; + /* debug_printf("b64d: '%c'\n", y); */ + if (y > 127 || (y = dec64table[y]) == 255) return -1; *result++ = (x << 2) | (y >> 4); + /* debug_printf("b64d: -> %02x\n", result[-1]); */ - if ((x = *code++) == '=') + while (isspace(x = *code++)) ; + /* debug_printf("b64d: '%c'\n", x); */ + if (x == '=') /* endmarker, but there should be another */ { - if (*code++ != '=' || *code != 0) return -1; + while (isspace(x = *code++)) ; + /* debug_printf("b64d: '%c'\n", x); */ + if (x != '=') return -1; + while (isspace(y = *code++)) ; + if (y != 0) return -1; + /* debug_printf("b64d: DONE\n"); */ + break; } else { if (x > 127 || (x = dec64table[x]) == 255) return -1; *result++ = (y << 4) | (x >> 2); - if ((y = (*code++)) == '=') + /* debug_printf("b64d: -> %02x\n", result[-1]); */ + + while (isspace(y = *code++)) ; + /* debug_printf("b64d: '%c'\n", y); */ + if (y == '=') { - if (*code != 0) return -1; + while (isspace(y = *code++)) ; + if (y != 0) return -1; + /* debug_printf("b64d: DONE\n"); */ + break; } else { if (y > 127 || (y = dec64table[y]) == 255) return -1; *result++ = (x << 6) | y; + /* debug_printf("b64d: -> %02x\n", result[-1]); */ } } } @@ -192,23 +221,6 @@ return result - *ptr; } -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* -/************************************************* - /************************************************* * Encode byte-string in base 64 * *************************************************/ @@ -231,14 +243,14 @@ static uschar *enc64table = US"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; uschar * -b64encode(uschar *clear, int len) +b64encode_taint(const uschar * clear, int len, BOOL tainted) { -uschar *code = store_get(4*((len+2)/3) + 1); +uschar *code = store_get(4*((len+2)/3) + 1, tainted); uschar *p = code; while (len-- >0) { - register int x, y; + int x, y; x = *clear++; *p++ = enc64table[(x >> 2) & 63]; @@ -272,6 +284,12 @@ while (len-- >0) return code; } +uschar * +b64encode(const uschar * clear, int len) +{ +return b64encode_taint(clear, len, is_tainted(clear)); +} + /* End of base64.c */ /* vi: sw ai sw=2