[exim-cvs] Taint: track in ${utf8clean:} operator

Αρχική Σελίδα
Delete this message
Reply to this message
Συντάκτης: Exim Git Commits Mailing List
Ημερομηνία:  
Προς: exim-cvs
Αντικείμενο: [exim-cvs] Taint: track in ${utf8clean:} operator
Gitweb: https://git.exim.org/exim.git/commitdiff/e68def51cb753d730249565e630b549a73857ec1
Commit:     e68def51cb753d730249565e630b549a73857ec1
Parent:     75b6e26f5ee1d313ba0d5b835e287f06b9770559
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Thu Mar 5 16:20:26 2020 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Thu Mar 5 16:37:45 2020 +0000


    Taint: track in ${utf8clean:} operator
---
 src/src/expand.c    | 25 +++++++++++++++++--------
 src/src/functions.h | 12 ++++++++++++
 src/src/string.c    | 11 -----------
 3 files changed, 29 insertions(+), 19 deletions(-)


diff --git a/src/src/expand.c b/src/src/expand.c
index 660fe98..3c31843 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 df4b336..851cedd 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 9f1aeb8..4ef2fee 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.