Documentation for randint. Better randomness defaults. Fixes: #722
[exim.git] / src / src / filter.c
index e551abef86decbfeb7ee42e41d579583ebca1ad1..3fdd35427b79ef35cc35598701346499276db26c 100644 (file)
@@ -1,10 +1,10 @@
-/* $Cambridge: exim/src/src/filter.c,v 1.6 2005/11/10 15:00:46 ph10 Exp $ */
+/* $Cambridge: exim/src/src/filter.c,v 1.14 2007/01/08 10:50:18 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2005 */
+/* Copyright (c) University of Cambridge 1995 - 2007 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 
@@ -1044,6 +1044,13 @@ switch (command)
   case elif_command:
   case else_command:
   case endif_command:
+  if (seen_force || noerror_force)
+    {
+    *error_pointer = string_sprintf("\"seen\", \"unseen\", or \"noerror\" "
+      "near line %d is not followed by a command", line_number);
+    yield = FALSE;
+    }
+
   if (expect_endif > 0)
     had_else_endif = (command == elif_command)? had_elif :
                      (command == else_command)? had_else : had_endif;
@@ -1316,6 +1323,12 @@ switch (command)
 
   case seen_command:
   case unseen_command:
+  if (*ptr == 0)
+    {
+    *error_pointer = string_sprintf("\"seen\" or \"unseen\" "
+      "near line %d is not followed by a command", line_number);
+    yield = FALSE;
+    }
   if (seen_force)
     {
     *error_pointer = string_sprintf("\"seen\" or \"unseen\" repeated "
@@ -1331,6 +1344,12 @@ switch (command)
   /* So does noerror */
 
   case noerror_command:
+  if (*ptr == 0)
+    {
+    *error_pointer = string_sprintf("\"noerror\" "
+      "near line %d is not followed by a command", line_number);
+    yield = FALSE;
+    }
   noerror_force = TRUE;
   was_noerror = TRUE;
   break;
@@ -1414,7 +1433,7 @@ Returns:         TRUE if the condition is met
 static BOOL
 test_condition(condition_block *c, BOOL toplevel)
 {
-BOOL yield;
+BOOL yield = FALSE;
 const pcre *re;
 uschar *exp[2], *p, *pp;
 const uschar *regcomp_error = NULL;
@@ -1834,11 +1853,12 @@ while (commands != NULL)
 
     else
       {
+      if (s[0] != '/' && (filter_options & RDO_PREPEND_HOME) != 0 &&
+          deliver_home != NULL && deliver_home[0] != 0)
+        s = string_sprintf("%s/%s", deliver_home, s);
       DEBUG(D_filter) debug_printf("Filter: %ssave message to: %s%s\n",
         (commands->seen)? "" : "unseen ", s,
         commands->noerror? " (noerror)" : "");
-      if (s[0] != '/' && deliver_home != NULL && deliver_home[0] != 0)
-        s = string_sprintf("%s/%s", deliver_home, s);
 
       /* Create the new address and add it to the chain, setting the
       af_pfr and af_file flags, the af_ignore_error flag if necessary, and the
@@ -2166,7 +2186,6 @@ while (commands != NULL)
                   string_printing(s), command_list[commands->command]);
                 return FF_ERROR;
                 }
-              pp++;
               }
             p = pp;
             }
@@ -2211,6 +2230,7 @@ while (commands != NULL)
       uschar *to = commands->args[mailarg_index_to].u;
       int size = 0;
       int ptr = 0;
+      int badflag = 0;
 
       if (to == NULL) to = expand_string(US"$reply_address");
       while (isspace(*to)) to++;
@@ -2240,9 +2260,10 @@ while (commands != NULL)
         }
 
       /* Create the "address" for the autoreply. This is used only for logging,
-      as the actual recipients are extraced from the To: line by -t. We use the
+      as the actual recipients are extracted from the To: line by -t. We use the
       same logic here to extract the working addresses (there may be more than
-      one). */
+      one). Just in case there are a vast number of addresses, stop when the
+      string gets too long. */
 
       tt = to;
       while (*tt != 0)
@@ -2268,17 +2289,29 @@ while (commands != NULL)
             Ustrlen(recipient));
           }
 
+        /* Check size */
+
+        if (ptr > 256)
+          {
+          log_addr = string_cat(log_addr, &size, &ptr, US", ...", 5);
+          break;
+          }
+
         /* Move on past this address */
 
         tt = ss + (*ss? 1:0);
         while (isspace(*tt)) tt++;
         }
 
-      if (log_addr == NULL) log_addr = string_sprintf("invalid-to-line");
-        else log_addr[ptr] = 0;
+      if (log_addr == NULL)
+        {
+        log_addr = string_sprintf(">**bad-reply**");
+        badflag = af_bad_reply;
+        }
+      else log_addr[ptr] = 0;
 
       addr = deliver_make_addr(log_addr, FALSE);
-      setflag(addr, af_pfr);
+      setflag(addr, (af_pfr|badflag));
       if (commands->noerror) setflag(addr, af_ignore_error);
       addr->next = *generated;
       *generated = addr;