Skip to content

Commit

Permalink
Taint: track in ${utf8clean:} operator
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeremy Harris committed Mar 5, 2020
1 parent 75b6e26 commit e68def5
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 19 deletions.
25 changes: 17 additions & 8 deletions src/src/expand.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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"?"

Expand All @@ -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++;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
12 changes: 12 additions & 0 deletions src/src/functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__)
Expand Down
11 changes: 0 additions & 11 deletions src/src/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
/*************************************************
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit e68def5

Please sign in to comment.