Fix taint trap in parse_fix_phrase(). Bug 2617
[exim.git] / src / src / rewrite.c
index 221b438b8e683d6c9dab64466614f7e92f2a51b1..7bff8a27318bd9959ab8e650e5c395bf368ccd6d 100644 (file)
@@ -292,16 +292,11 @@ for (rewrite_rule * rule = rewrite_rules;
         uschar *p1 = new + start - 1;
         uschar *p2 = new + end + 1;
         const uschar *pf1, *pf2;
-        uschar buff1[256], buff2[256];
 
         while (p1 > new && p1[-1] == ' ') p1--;
-        pf1 = parse_fix_phrase(new, p1 - new, buff1, sizeof(buff1));
+        pf1 = parse_fix_phrase(new, p1 - new);
         while (*p2 == ' ') p2++;
-        pf2 = parse_fix_phrase(p2, Ustrlen(p2), buff2, sizeof(buff2));
-
-        /* Note that pf1 and pf2 are NOT necessarily buff1 and buff2. For
-        a non-RFC 2047 phrase that does not need to be RFC 2822 quoted, they
-        will be buff1+1 and buff2+1. */
+        pf2 = parse_fix_phrase(p2, Ustrlen(p2));
 
         start = Ustrlen(pf1) + start + new - p1;
         end = start + Ustrlen(newparsed);
@@ -454,7 +449,7 @@ rewrite_one_header(header_line *h, int flag,
 {
 int lastnewline = 0;
 header_line *newh = NULL;
-void *function_reset_point = store_get(0);
+rmark function_reset_point = store_mark();
 uschar *s = Ustrchr(h->text, ':') + 1;
 while (isspace(*s)) s++;
 
@@ -475,7 +470,7 @@ while (*s)
   uschar *sprev;
   uschar *ss = parse_find_address_end(s, FALSE);
   uschar *recipient, *new, *errmess;
-  void *loop_reset_point = store_get(0);
+  rmark loop_reset_point = store_mark();
   BOOL changed = FALSE;
   int terminator = *ss;
   int start, end, domain;
@@ -496,7 +491,7 @@ while (*s)
 
   if (!recipient)
     {
-    store_reset(loop_reset_point);
+    loop_reset_point = store_reset(loop_reset_point);
     continue;
     }
 
@@ -543,7 +538,7 @@ while (*s)
     if (changed && ((is_recipient && !f.allow_unqualified_recipient) ||
                     (!is_recipient && !f.allow_unqualified_sender)))
       {
-      store_reset(loop_reset_point);
+      loop_reset_point = store_reset(loop_reset_point);
       continue;
       }
     }
@@ -575,7 +570,7 @@ while (*s)
   point, because we may have a rewritten line from a previous time round the
   loop. */
 
-  if (!changed) store_reset(loop_reset_point);
+  if (!changed) loop_reset_point = store_reset(loop_reset_point);
 
   /* If the address has changed, create a new header containing the
   rewritten address. We do not need to set the chain pointers at this
@@ -592,9 +587,9 @@ while (*s)
     int newlen = Ustrlen(new);
     int oldlen = end - start;
 
-    header_line *prev = (newh == NULL)? h : newh;
-    uschar *newt = store_malloc(prev->slen - oldlen + newlen + 4);
-    uschar *newtstart = newt;
+    header_line * prev = newh ? newh : h;
+    uschar * newt = store_get_perm(prev->slen - oldlen + newlen + 4, TRUE);
+    uschar * newtstart = newt;
 
     int type = prev->type;
     int slen = prev->slen - oldlen + newlen;
@@ -633,7 +628,7 @@ while (*s)
       if (*p != '\n')
         {
         lastnewline = newt - newtstart;
-        Ustrcat(newt, "\n\t");
+        Ustrcat(newt, US"\n\t");
         slen += 2;
         }
       }
@@ -656,11 +651,11 @@ while (*s)
     rewritten copy from a previous time round this loop. */
 
     store_reset(function_reset_point);
-    newh = store_get(sizeof(header_line));
+    function_reset_point = store_mark();
+    newh = store_get(sizeof(header_line), FALSE);
     newh->type = type;
     newh->slen = slen;
     newh->text = string_copyn(newtstart, slen);
-    store_free(newtstart);
 
     /* Set up for scanning the rest of the header */