summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2020-03-05 16:20:26 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2020-03-05 16:37:45 +0000
commite68def51cb753d730249565e630b549a73857ec1 (patch)
treecfb40771434a5c74f63b65617cb0acafc7da1004 /src
parent75b6e26f5ee1d313ba0d5b835e287f06b9770559 (diff)
downloadexim4-e68def51cb753d730249565e630b549a73857ec1.tar.gz
Taint: track in ${utf8clean:} operator
Diffstat (limited to 'src')
-rw-r--r--src/src/expand.c25
-rw-r--r--src/src/functions.h12
-rw-r--r--src/src/string.c11
3 files changed, 29 insertions, 19 deletions
diff --git a/src/src/expand.c b/src/src/expand.c
index 660fe98cf..3c3184347 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -7631,7 +7631,7 @@ while (*s != 0)
case EOP_QUOTE_LOCAL_PART:
if (!arg)
{
- BOOL needs_quote = (*sub == 0); /* TRUE for empty string */
+ BOOL needs_quote = (!*sub); /* TRUE for empty string */
uschar *t = sub - 1;
if (c == EOP_QUOTE)
@@ -7751,10 +7751,10 @@ while (*s != 0)
case EOP_FROM_UTF8:
{
- while (*sub != 0)
+ uschar * buff = store_get(4, is_tainted(sub));
+ while (*sub)
{
int c;
- uschar buff[4];
GETUTF8INC(c, sub);
if (c > 255) c = '_';
buff[0] = c;
@@ -7763,7 +7763,7 @@ while (*s != 0)
continue;
}
- /* replace illegal UTF-8 sequences by replacement character */
+ /* replace illegal UTF-8 sequences by replacement character */
#define UTF8_REPLACEMENT_CHAR US"?"
@@ -7775,7 +7775,17 @@ while (*s != 0)
int complete;
uschar seq_buff[4]; /* accumulate utf-8 here */
- while (*sub != 0)
+ /* Manually track tainting, as we deal in individual chars below */
+
+ if (is_tainted(sub))
+ if (yield->s && yield->ptr)
+ gstring_rebuffer(yield);
+ else
+ yield->s = store_get(yield->size = Ustrlen(sub), TRUE);
+
+ /* Check the UTF-8, byte-by-byte */
+
+ while (*sub)
{
complete = 0;
uschar c = *sub++;
@@ -7801,7 +7811,7 @@ while (*s != 0)
}
else /* no bytes left: new sequence */
{
- if((c & 0x80) == 0) /* 1-byte sequence, US-ASCII, keep it */
+ if(!(c & 0x80)) /* 1-byte sequence, US-ASCII, keep it */
{
yield = string_catn(yield, &c, 1);
continue;
@@ -7846,9 +7856,8 @@ while (*s != 0)
* Eg, ${length_1:フィル} is one byte, not one character, so we expect
* ${utf8clean:${length_1:フィル}} to yield '?' */
if (bytes_left != 0)
- {
yield = string_catn(yield, UTF8_REPLACEMENT_CHAR, 1);
- }
+
continue;
}
diff --git a/src/src/functions.h b/src/src/functions.h
index df4b33606..851cedd3f 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -919,6 +919,18 @@ va_end(ap);
return g;
}
+
+/* Copy the content of a string to tainted memory */
+
+static inline void
+gstring_rebuffer(gstring * g)
+{
+uschar * s = store_get(g->size, TRUE);
+memcpy(s, g->s, g->ptr);
+g->s = s;
+}
+
+
/******************************************************************************/
#define store_get_dns_answer() store_get_dns_answer_trc(CUS __FUNCTION__, __LINE__)
diff --git a/src/src/string.c b/src/src/string.c
index 9f1aeb81d..4ef2fee62 100644
--- a/src/src/string.c
+++ b/src/src/string.c
@@ -12,7 +12,6 @@ utilities and tests, and are cut out by the COMPILE_UTILITY macro. */
#include "exim.h"
#include <assert.h>
-static void gstring_rebuffer(gstring * g);
#ifndef COMPILE_UTILITY
/*************************************************
@@ -1243,16 +1242,6 @@ return !!gp;
-/* Copy the content of a string to tainted memory */
-static void
-gstring_rebuffer(gstring * g)
-{
-uschar * s = store_get(g->size, TRUE);
-memcpy(s, g->s, g->ptr);
-g->s = s;
-}
-
-
/* Build or append to a growing-string, sprintf-style.