tidying
[exim.git] / src / src / mime.c
index 80e820b2bcd0123917e92a2546c774b32c720194..d47b569827795cbfaeed88d6a47319c895bb4d77 100644 (file)
@@ -2,9 +2,9 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004, 2015
+/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004 - 2015
  * License: GPL
- * Copyright (c) The Exim Maintainers 2016
+ * Copyright (c) The Exim Maintainers 2015 - 2018
  */
 
 #include "exim.h"
@@ -16,6 +16,7 @@ FILE *mime_stream = NULL;
 uschar *mime_current_boundary = NULL;
 
 static mime_header mime_header_list[] = {
+  /*   name                    namelen         value */
   { US"content-type:",              13, &mime_content_type },
   { US"content-disposition:",       20, &mime_content_disposition },
   { US"content-transfer-encoding:", 26, &mime_content_transfer_encoding },
@@ -26,6 +27,7 @@ static mime_header mime_header_list[] = {
 static int mime_header_list_size = nelem(mime_header_list);
 
 static mime_parameter mime_parameter_list[] = {
+  /*   name    namelen  value */
   { US"name=",     5, &mime_filename },
   { US"filename=", 9, &mime_filename },
   { US"charset=",  8, &mime_charset  },
@@ -336,17 +338,16 @@ while(!done)
     if ( ((c == '\t') || (c == ' ')) && (header_value_mode == 1) )
       continue;
 
-      /* we have hit a non-whitespace char, start copying value data */
-      header_value_mode = 2;
+    /* we have hit a non-whitespace char, start copying value data */
+    header_value_mode = 2;
 
-      if (c == '"')       /* flip "quoted" mode */
-        header_value_mode = header_value_mode==2 ? 3 : 2;
+    if (c == '"')       /* flip "quoted" mode */
+      header_value_mode = header_value_mode==2 ? 3 : 2;
 
-      /* leave value mode on unquoted ';' */
-      if (header_value_mode == 2 && c == ';') {
-        header_value_mode = 0;
-      };
-      /* -------------------------------- */
+    /* leave value mode on unquoted ';' */
+    if (header_value_mode == 2 && c == ';')
+      header_value_mode = 0;
+    /* -------------------------------- */
     }
   else
     {
@@ -394,10 +395,7 @@ if ((num_copied > 0) && (header[num_copied-1] != ';'))
 header[num_copied] = '\0';
 
 /* return 0 for EOF or empty line */
-if ((c == EOF) || (num_copied == 1))
-  return 0;
-else
-  return 1;
+return c == EOF || num_copied == 1 ? 0 : 1;
 }
 
 
@@ -432,8 +430,7 @@ static uschar *
 mime_param_val(uschar ** sp)
 {
 uschar * s = *sp;
-uschar * val = NULL;
-int size = 0, ptr = 0;
+gstring * val = NULL;
 
 /* debug_printf_indent("   considering paramval '%s'\n", s); */
 
@@ -442,14 +439,13 @@ while (*s && *s != ';')           /* ; terminates */
     {
     s++;                       /* skip opening " */
     while (*s && *s != '"')    /* " protects ; */
-      val = string_catn(val, &size, &ptr, s++, 1);
+      val = string_catn(val, s++, 1);
     if (*s) s++;               /* skip closing " */
     }
   else
-    val = string_catn(val, &size, &ptr, s++, 1);
-if (val) val[ptr] = '\0';
+    val = string_catn(val, s++, 1);
 *sp = s;
-return val;
+return string_from_gstring(val);
 }
 
 static uschar *
@@ -472,27 +468,26 @@ return s;
 static uschar *
 rfc2231_to_2047(const uschar * fname, const uschar * charset, int * len)
 {
-int size = 0, ptr = 0;
-uschar * val = string_catn(NULL, &size, &ptr, US"=?", 2);
+gstring * val = string_catn(NULL, US"=?", 2);
 uschar c;
 
 if (charset)
-  val = string_cat(val, &size, &ptr, charset);
-val = string_catn(val, &size, &ptr, US"?Q?", 3);
+  val = string_cat(val, charset);
+val = string_catn(val, US"?Q?", 3);
 
 while ((c = *fname))
   if (c == '%' && isxdigit(fname[1]) && isxdigit(fname[2]))
     {
-    val = string_catn(val, &size, &ptr, US"=", 1);
-    val = string_catn(val, &size, &ptr, ++fname, 2);
+    val = string_catn(val, US"=", 1);
+    val = string_catn(val, ++fname, 2);
     fname += 2;
     }
   else
-    val = string_catn(val, &size, &ptr, fname++, 1);
+    val = string_catn(val, fname++, 1);
 
-val = string_catn(val, &size, &ptr, US"?=", 2);
-val[*len = ptr] = '\0';
-return val;
+val = string_catn(val, US"?=", 2);
+*len = val->ptr;
+return string_from_gstring(val);
 }
 
 
@@ -504,8 +499,8 @@ int rc = OK;
 uschar * header = NULL;
 struct mime_boundary_context nested_context;
 
-/* reserve a line buffer to work in */
-header = store_get(MIME_MAX_HEADER_SIZE+1);
+/* reserve a line buffer to work in.  Assume tainted data. */
+header = store_get(MIME_MAX_HEADER_SIZE+1, TRUE);
 
 /* Not actually used at the moment, but will be vital to fixing
  * some RFC 2046 nonconformance later... */
@@ -559,11 +554,9 @@ while(1)
 
   /* parse headers, set up expansion variables */
   while (mime_get_header(f, header))
-    {
-    struct mime_header * mh;
 
     /* look for interesting headers */
-    for (mh = mime_header_list;
+    for (struct mime_header * mh = mime_header_list;
         mh < mime_header_list + mime_header_list_size;
         mh++) if (strncmpic(mh->name, header, mh->namelen) == 0)
       {
@@ -591,8 +584,6 @@ while(1)
 
        while (*p)
          {
-         mime_parameter * mp;
-
          DEBUG(D_acl) debug_printf_indent("MIME:   considering paramlist '%s'\n", p);
 
          if (  !mime_filename
@@ -648,9 +639,7 @@ while(1)
                  NULL, &err_msg);
                DEBUG(D_acl) debug_printf_indent("MIME:    plain-name %s\n", temp_string);
 
-               size = Ustrlen(temp_string);
-
-               if (size == slen)
+               if (!temp_string || (size = Ustrlen(temp_string))  == slen)
                  decoding_failed = TRUE;
                else
                  /* build up a decoded filename over successive
@@ -665,7 +654,7 @@ while(1)
 
          else
            /* look for interesting parameters */
-           for (mp = mime_parameter_list;
+           for (mime_parameter * mp = mime_parameter_list;
                 mp < mime_parameter_list + nelem(mime_parameter_list);
                 mp++
                ) if (strncmpic(mp->name, p, mp->namelen) == 0)
@@ -705,7 +694,6 @@ while(1)
          }
        }
       }
-    }
 
   /* set additional flag variables (easier access) */
   if (  mime_content_type