Revert introduction of alloc_insecure_tainted_data
[exim.git] / src / src / parse.c
index 8c1badd08366f1ccde4b293be8f4941730cabd25..cf673e7167b9541ad6e89264703bcbba6978f302 100644 (file)
@@ -1243,7 +1243,7 @@ Returns:      FF_DELIVERED      addresses extracted
 
 int
 parse_forward_list(const uschar *s, int options, address_item **anchor,
-  uschar **error, const uschar *incoming_domain, uschar *directory,
+  uschar **error, const uschar *incoming_domain, const uschar *directory,
   error_block **syntax_errors)
 {
 int count = 0;
@@ -1388,7 +1388,7 @@ for (;;)
       return FF_ERROR;
       }
 
-    if (flen > 255)
+    if (flen > sizeof(filename)-1)
       {
       *error = string_sprintf("included file name \"%s\" is too long", t);
       return FF_ERROR;
@@ -1414,16 +1414,22 @@ for (;;)
       return FF_ERROR;
       }
 
-    if ((*error = is_tainted2(filename, 0, "Tainted name '%s' for included file not permitted\n", filename)))
+    if (is_tainted(filename))
+      {
+      *error = string_sprintf("Tainted name '%s' for included file  not permitted\n",
+       filename);
       return FF_ERROR;
+      }
 
     /* Check file name if required */
 
     if (directory)
       {
       int len = Ustrlen(directory);
-      uschar * p = filename + len;
+      uschar * p;
 
+      while (len > 0 && directory[len-1] == '/') len--;                /* ignore trailing '/' */
+      p = filename + len;
       if (Ustrncmp(filename, directory, len) != 0 || *p != '/')
         {
         *error = string_sprintf("included file %s is not in directory %s",
@@ -1438,7 +1444,7 @@ for (;;)
       with a flag that fails symlinks. */
 
       {
-      int fd = exim_open2(CS directory, O_RDONLY);
+      int fd = exim_open2(CCS directory, O_RDONLY);
       if (fd < 0)
        {
        *error = string_sprintf("failed to open directory %s", directory);
@@ -1448,9 +1454,10 @@ for (;;)
        {
        uschar temp;
        int fd2;
-       uschar * q = p;
+       uschar * q = p + 1;             /* skip dividing '/' */
 
-       while (*++p && *p != '/') ;
+       while (*q == '/') q++;          /* skip extra '/' */
+       while (*++p && *p != '/') ;     /* end of component */
        temp = *p;
        *p = '\0';