* Exim - an Internet mail transport agent *
*************************************************/
+/* Copyright (c) The Exim Maintainers 2020 - 2023 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
-/* Copyright (c) The Exim Maintainers 2020 - 2021 */
/* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Functions for parsing addresses */
#ifdef STAND_ALONE
-address_item *deliver_make_addr(uschar *address, BOOL copy)
+address_item *
+deliver_make_addr(uschar *address, BOOL copy)
{
-address_item *addr = store_get(sizeof(address_item), FALSE);
+address_item *addr = store_get(sizeof(address_item), GET_UNTAINTED);
addr->next = NULL;
addr->parent = NULL;
addr->address = address;
return addr;
}
-uschar *rewrite_address(uschar *recipient, BOOL dummy1, BOOL dummy2, rewrite_rule
+uschar *
+rewrite_address(uschar *recipient, BOOL dummy1, BOOL dummy2, rewrite_rule
*dummy3, int dummy4)
{
return recipient;
}
-uschar *rewrite_address_qualify(uschar *recipient, BOOL dummy1)
+uschar *
+rewrite_address_qualify(uschar *recipient, BOOL dummy1)
{
return recipient;
}
*/
uschar *
-parse_find_address_end(const uschar *s, BOOL nl_ends)
+parse_find_address_end(const uschar * s, BOOL nl_ends)
{
BOOL source_routing = *s == '@';
-int no_term = source_routing? 1 : 0;
+int no_term = source_routing ? 1 : 0;
-while (*s != 0 && (*s != ',' || no_term > 0) && (*s != '\n' || !nl_ends))
+while (*s && (*s != ',' || no_term > 0) && (*s != '\n' || !nl_ends))
{
/* Skip single quoted characters. Strictly these should not occur outside
quoted strings in RFC 822 addresses, but they can in RFC 821 addresses. Pity
about the lack of consistency, isn't it? */
- if (*s == '\\' && s[1] != 0) s += 2;
+ if (*s == '\\' && s[1])
+ s += 2;
/* Skip quoted items that are not inside brackets. Note that
quoted pairs are allowed inside quoted strings. */
else if (*s == '\"')
- {
- while (*(++s) != 0 && (*s != '\n' || !nl_ends))
+ while (*++s && (*s != '\n' || !nl_ends))
{
- if (*s == '\\' && s[1] != 0) s++;
- else if (*s == '\"') { s++; break; }
+ if (*s == '\\' && s[1])
+ s++;
+ else if (*s == '\"')
+ { s++; break; }
}
- }
/* Skip comments, which may include nested brackets, but quotes
are not recognized inside comments, though quoted pairs are. */
else if (*s == '(')
{
int level = 1;
- while (*(++s) != 0 && (*s != '\n' || !nl_ends))
- {
- if (*s == '\\' && s[1] != 0) s++;
- else if (*s == '(') level++;
- else if (*s == ')' && --level <= 0) { s++; break; }
- }
+ while (*++s && (*s != '\n' || !nl_ends))
+ if (*s == '\\' && s[1])
+ s++;
+ else if (*s == '(')
+ level++;
+ else if (*s == ')' && --level <= 0)
+ { s++; break; }
}
/* Non-special character; just advance. Passing the colon in a source
if (*s == '<')
{
source_routing = s[1] == '@';
- no_term = source_routing? 2 : 1;
+ no_term = source_routing ? 2 : 1;
}
- else if (*s == '>') no_term--;
- else if (source_routing && *s == ':') no_term--;
+ else if (*s == '>')
+ no_term--;
+ else if (source_routing && *s == ':')
+ no_term--;
s++;
}
}
parse_extract_address(const uschar *mailbox, uschar **errorptr, int *start, int *end,
int *domain, BOOL allow_null)
{
-uschar *yield = store_get(Ustrlen(mailbox) + 1, is_tainted(mailbox));
+uschar * yield = store_get(Ustrlen(mailbox) + 1, mailbox);
const uschar *startptr, *endptr;
const uschar *s = US mailbox;
uschar *t = US yield;
if (*s != '@' && *s != '<')
{
- if (*s == 0 || *s == ';')
+ if (!*s || *s == ';')
{
if (!*t) FAILED(US"empty address");
endptr = last_comment_position;
*/
const uschar *
-parse_quote_2047(const uschar *string, int len, const uschar *charset,
+parse_quote_2047(const uschar * string, int len, const uschar * charset,
BOOL fold)
{
const uschar * s = string;
-int hlen, l;
+int hlen, line_off;
BOOL coded = FALSE;
BOOL first_byte = FALSE;
gstring * g =
- string_fmt_append(NULL, "=?%s?Q?", charset ? charset : US"iso-8859-1");
+ string_fmt_append(NULL, "=?%s?Q?%n", charset ? charset : US"iso-8859-1", &hlen);
-hlen = l = g->ptr;
+line_off = hlen;
for (s = string; len > 0; s++, len--)
{
int ch = *s;
- if (g->ptr - l > 67 && !first_byte)
+ if (g->ptr - line_off > 67 && !first_byte)
{
g = fold ? string_catn(g, US"?=\n ", 4) : string_catn(g, US"?= ", 3);
- l = g->ptr;
+ line_off = g->ptr;
g = string_catn(g, g->s, hlen);
}
/* No non-printers; use the RFC 822 quoting rules */
if (len <= 0 || len >= INT_MAX/4)
- {
- return string_copy_taint(CUS"", is_tainted(phrase));
- }
+ return string_copy_taint(CUS"", phrase);
-buffer = store_get((len+1)*4, is_tainted(phrase));
+buffer = store_get((len+1)*4, phrase);
s = phrase;
end = s + len;
return FF_ERROR;
}
- if ((*error = is_tainted2(filename, 0, "Tainted name '%s' for included file not permitted\n", filename)))
+ if (is_tainted(filename))
+ {
+ *error = string_sprintf("Tainted name '%s' for included file not permitted\n",
+ filename);
return FF_ERROR;
+ }
/* Check file name if required */
if (directory)
{
int len = Ustrlen(directory);
- uschar * p = filename + len;
+ uschar * p;
+ while (len > 0 && directory[len-1] == '/') len--; /* ignore trailing '/' */
+ p = filename + len;
if (Ustrncmp(filename, directory, len) != 0 || *p != '/')
{
*error = string_sprintf("included file %s is not in directory %s",
{
uschar temp;
int fd2;
- uschar * q = p;
+ uschar * q = p + 1; /* skip dividing '/' */
- while (*++p && *p != '/') ;
+ while (*q == '/') q++; /* skip extra '/' */
+ while (*++p && *p != '/') ; /* end of component */
temp = *p;
*p = '\0';
return FF_ERROR;
}
- filebuf = store_get(statbuf.st_size + 1, is_tainted(filename));
+ filebuf = store_get(statbuf.st_size + 1, filename);
if (fread(filebuf, 1, statbuf.st_size, f) != statbuf.st_size)
{
*error = string_sprintf("error while reading included file %s: %s",
if ((*s_ltd == '|' || *s_ltd == '/') && (!recipient || domain == 0))
{
- uschar * t = store_get(Ustrlen(s_ltd) + 1, is_tainted(s_ltd));
+ uschar * t = store_get(Ustrlen(s_ltd) + 1, s_ltd);
uschar * p = t, * q = s_ltd;
while (*q)
if (syntax_errors)
{
- error_block * e = store_get(sizeof(error_block), FALSE);
+ error_block * e = store_get(sizeof(error_block), GET_UNTAINTED);
error_block * last = *syntax_errors;
if (last)
{
line. Therefore, take care to release unwanted store afterwards. */
reset_point = store_mark();
-id = *yield = store_get(Ustrlen(str) + 1, is_tainted(str));
+id = *yield = store_get(Ustrlen(str) + 1, str);
*id++ = *str++;
str = read_addr_spec(str, id, '>', error, &domain);