X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/184e88237dea64ce48076cdd0184612d057cbafd..1d28cc061677bd07d9bed48dd84bd5c590247043:/src/src/rfc2047.c diff --git a/src/src/rfc2047.c b/src/src/rfc2047.c index d2a6eb182..c40518a5d 100644 --- a/src/src/rfc2047.c +++ b/src/src/rfc2047.c @@ -1,11 +1,11 @@ -/* $Cambridge: exim/src/src/rfc2047.c,v 1.4 2007/01/08 10:50:18 ph10 Exp $ */ - /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2007 */ +/* Copyright (c) The Exim Maintainers 2020 - 2022 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file contains a function for decoding message header lines that may contain encoded "words" according to the rules described in @@ -48,11 +48,11 @@ rfc2047_qpdecode(uschar *string, uschar **ptrptr) int len = 0; uschar *ptr; -ptr = *ptrptr = store_get(Ustrlen(string) + 1); /* No longer than this */ +ptr = *ptrptr = store_get(Ustrlen(string) + 1, string); /* No longer than this */ while (*string != 0) { - register int ch = *string++; + int ch = *string++; if (ch == '_') *ptr++ = ' '; else if (ch == '=') @@ -122,7 +122,7 @@ for (;; string = mimeword + 2) encoding = toupper((*q1ptr)[1]); **endptr = 0; if (encoding == 'B') - dlen = auth_b64decode(*q2ptr+1, dptrptr); + dlen = b64decode(*q2ptr+1, dptrptr); else if (encoding == 'Q') dlen = rfc2047_qpdecode(*q2ptr+1, dptrptr); **endptr = '?'; /* restore */ @@ -187,21 +187,21 @@ Returns: the decoded, converted string, or NULL on error; if there are */ uschar * -rfc2047_decode2(uschar *string, BOOL lencheck, uschar *target, int zeroval, - int *lenptr, int *sizeptr, uschar **error) +rfc2047_decode2(uschar *string, BOOL lencheck, const uschar *target, + int zeroval, int *lenptr, int *sizeptr, uschar **error) { -int ptr = 0; int size = Ustrlen(string); size_t dlen; -uschar *dptr, *yield; +uschar *dptr; +gstring *yield; uschar *mimeword, *q1, *q2, *endword; *error = NULL; mimeword = decode_mimeword(string, lencheck, &q1, &q2, &endword, &dlen, &dptr); -if (mimeword == NULL) +if (!mimeword) { - if (lenptr != NULL) *lenptr = size; + if (lenptr) *lenptr = size; return string; } @@ -210,9 +210,12 @@ building the result as we go. The result may be longer than the input if it is translated into a multibyte code such as UTF-8. That's why we use the dynamic string building code. */ -yield = store_get(++size); +yield = store_get(sizeof(gstring) + ++size, string); +yield->size = size; +yield->ptr = 0; +yield->s = US(yield + 1); -while (mimeword != NULL) +while (mimeword) { #if HAVE_ICONV @@ -220,7 +223,8 @@ while (mimeword != NULL) #endif if (mimeword != string) - yield = string_cat(yield, &size, &ptr, string, mimeword - string); + yield = string_catn(yield, string, mimeword - string); +/*XXX that might have to convert an untainted string to a tainted one */ /* Do a charset translation if required. This is supported only on hosts that have the iconv() function. Translation errors set error, but carry on, @@ -231,17 +235,11 @@ while (mimeword != NULL) #if HAVE_ICONV *q1 = 0; - if (target != NULL && strcmpic(target, mimeword+2) != 0) - { - icd = iconv_open(CS target, CS(mimeword+2)); - - if (icd == (iconv_t)(-1)) - { + if (target && strcmpic(target, mimeword+2) != 0) + if ((icd = iconv_open(CS target, CS(mimeword+2))) == (iconv_t)-1) *error = string_sprintf("iconv_open(\"%s\", \"%s\") failed: %s%s", target, mimeword+2, strerror(errno), (errno == EINVAL)? " (maybe unsupported conversion)" : ""); - } - } *q1 = '?'; #endif @@ -279,7 +277,7 @@ while (mimeword != NULL) else { DEBUG(D_any) debug_printf("iconv error translating \"%.*s\" to %s: " - "%s\n", endword + 2 - mimeword, mimeword, target, strerror(errno)); + "%s\n", (int)(endword + 2 - mimeword), mimeword, target, strerror(errno)); } } @@ -299,15 +297,12 @@ while (mimeword != NULL) /* Deal with zero values; convert them if requested. */ if (zeroval != 0) - { - int i; - for (i = 0; i < tlen; i++) + for (int i = 0; i < tlen; i++) if (tptr[i] == 0) tptr[i] = zeroval; - } /* Add the new string onto the result */ - yield = string_cat(yield, &size, &ptr, tptr, tlen); + yield = string_catn(yield, tptr, tlen); } #if HAVE_ICONV @@ -319,7 +314,7 @@ while (mimeword != NULL) string = endword + 2; mimeword = decode_mimeword(string, lencheck, &q1, &q2, &endword, &dlen, &dptr); - if (mimeword != NULL) + if (mimeword) { uschar *s = string; while (isspace(*s)) s++; @@ -330,11 +325,11 @@ while (mimeword != NULL) /* Copy the remaining characters of the string, zero-terminate it, and return the length as well if requested. */ -yield = string_cat(yield, &size, &ptr, string, Ustrlen(string)); -yield[ptr] = 0; -if (lenptr != NULL) *lenptr = ptr; -if (sizeptr != NULL) *sizeptr = size; -return yield; +yield = string_cat(yield, string); + +if (lenptr) *lenptr = yield->ptr; +if (sizeptr) *sizeptr = yield->size; +return string_from_gstring(yield); } @@ -342,7 +337,7 @@ return yield; argument. */ uschar * -rfc2047_decode(uschar *string, BOOL lencheck, uschar *target, int zeroval, +rfc2047_decode(uschar *string, BOOL lencheck, const uschar *target, int zeroval, int *lenptr, uschar **error) { return rfc2047_decode2(string, lencheck, target, zeroval, lenptr, NULL, error);