From: Jeremy Harris Date: Thu, 5 Mar 2020 16:20:26 +0000 (+0000) Subject: Taint: track in ${utf8clean:} operator X-Git-Tag: exim-4_94_RC0~75 X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=commitdiff_plain;h=e68def51cb753d730249565e630b549a73857ec1 Taint: track in ${utf8clean:} operator --- 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 -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.