Add macro support to -be expansion test mode. Bug 1623
authorJeremy Harris <jgh146exb@wizmail.org>
Tue, 31 Oct 2017 15:31:50 +0000 (15:31 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 31 Oct 2017 15:31:50 +0000 (15:31 +0000)
22 files changed:
doc/doc-docbook/spec.xfpt
doc/doc-txt/NewStuff
src/src/exim.c
src/src/functions.h
src/src/readconf.c
src/src/sieve.c
test/scripts/0000-Basic/0002
test/scripts/0000-Basic/0542
test/scripts/3300-crypteq/3300
test/scripts/4200-International/4200
test/stderr/0002
test/stderr/0236
test/stderr/0387
test/stderr/0484
test/stderr/2200
test/stderr/2600
test/stderr/3000
test/stderr/3212
test/stdout/0002
test/stdout/0542
test/stdout/3300
test/stdout/4200

index a9a048e..13fcad7 100644 (file)
@@ -2791,6 +2791,13 @@ files or databases you are using, you must exit and restart Exim before trying
 the same lookup again. Otherwise, because each Exim process caches the results
 of lookups, you will just get the same result as before.
 
+.new
+Macro processing is done on lines before string-expansion: new macros can be
+defined and macros will be expanded.
+Because macros in the config file are often used for secrets, those are only
+available to admin users.
+.wen
+
 .vitem &%-bem%&&~<&'filename'&>
 .oindex "&%-bem%&"
 .cindex "testing" "string expansion"
index 6d875d5..22af135 100644 (file)
@@ -61,6 +61,9 @@ Version 4.90
 15. TCP Fast Open used, with data-on-SYN, for client SMTP via SOCKS5 proxy,
     for ${readsocket } expansions, and for ClamAV.
 
+16. The "-be" expansion test mode now supports macros.  Macros are expanded
+    in test lines, and new macros can be defined.
+
 
 Version 4.89
 ------------
index 7dd0845..d71af0a 100644 (file)
@@ -1458,6 +1458,39 @@ return TRUE;
 
 
 /*************************************************
+*          Expansion testing                    *
+*************************************************/
+
+/* Expand and print one item, doing macro-processing.
+
+Arguments:
+  item         line for expansion
+*/
+
+static void
+expansion_test_line(uschar * line)
+{
+int len;
+BOOL dummy_macexp;
+
+Ustrncpy(big_buffer, line, big_buffer_size);
+big_buffer[big_buffer_size-1] = '\0';
+len = Ustrlen(big_buffer);
+
+(void) macros_expand(0, &len, &dummy_macexp);
+
+if (isupper(big_buffer[0]))
+  {
+  if (macro_read_assignment(big_buffer))
+    printf("Defined macro '%s'\n", mlast->name);
+  }
+else
+  if ((line = expand_string(big_buffer))) printf("%s\n", CS line);
+  else printf("Failed: %s\n", expand_string_message);
+}
+
+
+/*************************************************
 *          Entry point and high-level code       *
 *************************************************/
 
@@ -4988,7 +5021,7 @@ if (expansion_test)
   /* Read a test message from a file. We fudge it up to be on stdin, saving
   stdin itself for later reading of expansion strings. */
 
-  else if (expansion_test_message != NULL)
+  else if (expansion_test_message)
     {
     int save_stdin = dup(0);
     int fd = Uopen(expansion_test_message, O_RDONLY, 0);
@@ -5008,6 +5041,10 @@ if (expansion_test)
     clearerr(stdin);               /* Required by Darwin */
     }
 
+  /* Only admin users may see config-file macros this way */
+
+  if (!admin_user) macros = mlast = NULL;
+
   /* Allow $recipients for this testing */
 
   enable_dollar_recipients = TRUE;
@@ -5015,15 +5052,8 @@ if (expansion_test)
   /* Expand command line items */
 
   if (recipients_arg < argc)
-    {
     while (recipients_arg < argc)
-      {
-      uschar *s = argv[recipients_arg++];
-      uschar *ss = expand_string(s);
-      if (ss == NULL) printf ("Failed: %s\n", expand_string_message);
-      else printf("%s\n", CS ss);
-      }
-    }
+      expansion_test_line(argv[recipients_arg++]);
 
   /* Read stdin */
 
@@ -5031,25 +5061,18 @@ if (expansion_test)
     {
     char *(*fn_readline)(const char *) = NULL;
     void (*fn_addhist)(const char *) = NULL;
+    uschar * s;
 
-    #ifdef USE_READLINE
+#ifdef USE_READLINE
     void *dlhandle = set_readline(&fn_readline, &fn_addhist);
-    #endif
+#endif
 
-    for (;;)
-      {
-      uschar *ss;
-      uschar *source = get_stdinput(fn_readline, fn_addhist);
-      if (source == NULL) break;
-      ss = expand_string(source);
-      if (ss == NULL)
-        printf ("Failed: %s\n", expand_string_message);
-      else printf("%s\n", CS ss);
-      }
+    while (s = get_stdinput(fn_readline, fn_addhist))
+      expansion_test_line(s);
 
-    #ifdef USE_READLINE
-    if (dlhandle != NULL) dlclose(dlhandle);
-    #endif
+#ifdef USE_READLINE
+    if (dlhandle) dlclose(dlhandle);
+#endif
     }
 
   /* The data file will be open after -Mset */
@@ -5060,7 +5083,7 @@ if (expansion_test)
     deliver_datafile = -1;
     }
 
-  exim_exit(EXIT_SUCCESS, US"main");
+  exim_exit(EXIT_SUCCESS, US"main: expansion test");
   }
 
 
index 1fe561f..e50fa6f 100644 (file)
@@ -257,6 +257,8 @@ extern int     log_create_as_exim(uschar *);
 extern void    log_close_all(void);
 
 extern macro_item * macro_create(const uschar *, const uschar *, BOOL);
+extern BOOL    macro_read_assignment(uschar *);
+extern uschar *macros_expand(int, int *, BOOL *);
 extern void    mainlog_close(void);
 #ifdef WITH_CONTENT_SCAN
 extern int     malware(const uschar *, int);
index b34372c..8d5f38c 100644 (file)
@@ -615,7 +615,10 @@ m->namelen = Ustrlen(name);
 m->replen = Ustrlen(val);
 m->name = name;
 m->replacement = val;
-mlast->next = m;
+if (mlast)
+  mlast->next = m;
+else
+  macros = m;
 mlast = m;
 return m;
 }
@@ -630,11 +633,11 @@ non-command line, macros is permitted using '==' instead of '='.
 Arguments:
   s            points to the start of the logical line
 
-Returns:       nothing
+Returns:       FALSE iff fatal error
 */
 
-static void
-read_macro_assignment(uschar *s)
+BOOL
+macro_read_assignment(uschar *s)
 {
 uschar name[64];
 int namelen = 0;
@@ -644,15 +647,21 @@ macro_item *m;
 while (isalnum(*s) || *s == '_')
   {
   if (namelen >= sizeof(name) - 1)
-    log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
+    {
+    log_write(0, LOG_PANIC|LOG_CONFIG_IN,
       "macro name too long (maximum is " SIZE_T_FMT " characters)", sizeof(name) - 1);
+    return FALSE;
+    }
   name[namelen++] = *s++;
   }
 name[namelen] = 0;
 
 while (isspace(*s)) s++;
 if (*s++ != '=')
-  log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "malformed macro definition");
+  {
+  log_write(0, LOG_PANIC|LOG_CONFIG_IN, "malformed macro definition");
+  return FALSE;
+  }
 
 if (*s == '=')
   {
@@ -675,15 +684,21 @@ for (m = macros; m; m = m->next)
   if (Ustrcmp(m->name, name) == 0)
     {
     if (!m->command_line && !redef)
-      log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "macro \"%s\" is already "
+      {
+      log_write(0, LOG_CONFIG|LOG_PANIC, "macro \"%s\" is already "
        "defined (use \"==\" if you want to redefine it", name);
+      return FALSE;
+      }
     break;
     }
 
   if (m->namelen < namelen && Ustrstr(name, m->name) != NULL)
-    log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "\"%s\" cannot be defined as "
+    {
+    log_write(0, LOG_CONFIG|LOG_PANIC, "\"%s\" cannot be defined as "
       "a macro because previously defined macro \"%s\" is a substring",
       name, m->name);
+    return FALSE;
+    }
 
   /* We cannot have this test, because it is documented that a substring
   macro is permitted (there is even an example).
@@ -697,7 +712,7 @@ for (m = macros; m; m = m->next)
 
 /* Check for an overriding command-line definition. */
 
-if (m && m->command_line) return;
+if (m && m->command_line) return TRUE;
 
 /* Redefinition must refer to an existing macro. */
 
@@ -708,18 +723,119 @@ if (redef)
     m->replacement = string_copy(s);
     }
   else
-    log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "can't redefine an undefined macro "
+    {
+    log_write(0, LOG_CONFIG|LOG_PANIC, "can't redefine an undefined macro "
       "\"%s\"", name);
+    return FALSE;
+    }
 
 /* We have a new definition. */
 else
   (void) macro_create(string_copy(name), string_copy(s), FALSE);
+return TRUE;
 }
 
 
 
 
 
+/* Process line for macros. The line is in big_buffer starting at offset len.
+Expand big_buffer if needed.  Handle definitions of new macros, and
+imacro expansions, rewriting the line in thw buffer.
+
+Arguments:
+ len           Offset in buffer of start of line
+ newlen                Pointer to offset of end of line, updated on return
+ macro_found   Pointer to return that a macro was expanded
+
+Return: pointer to first nonblank char in line
+*/
+
+uschar *
+macros_expand(int len, int * newlen, BOOL * macro_found)
+{
+uschar * ss = big_buffer + len;
+uschar * s;
+macro_item * m;
+
+/* Find the true start of the physical line - leading spaces are always
+ignored. */
+
+while (isspace(*ss)) ss++;
+
+/* Process the physical line for macros. If this is the start of the logical
+line, skip over initial text at the start of the line if it starts with an
+upper case character followed by a sequence of name characters and an equals
+sign, because that is the definition of a new macro, and we don't do
+replacement therein. */
+
+s = ss;
+if (len == 0 && isupper(*s))
+  {
+  while (isalnum(*s) || *s == '_') s++;
+  while (isspace(*s)) s++;
+  if (*s != '=') s = ss;          /* Not a macro definition */
+  }
+
+/* Skip leading chars which cannot start a macro name, to avoid multiple
+pointless rescans in Ustrstr calls. */
+
+while (*s && !isupper(*s) && *s != '_') s++;
+
+/* For each defined macro, scan the line (from after XXX= if present),
+replacing all occurrences of the macro. */
+
+*macro_found = FALSE;
+for (m = macros; m; m = m->next)
+  {
+  uschar * p, *pp;
+  uschar * t = s;
+
+  while ((p = Ustrstr(t, m->name)) != NULL)
+    {
+    int moveby;
+
+/* fprintf(stderr, "%s: matched '%s' in '%s'\n", __FUNCTION__, m->name, ss); */
+    /* Expand the buffer if necessary */
+
+    while (*newlen - m->namelen + m->replen + 1 > big_buffer_size)
+      {
+      int newsize = big_buffer_size + BIG_BUFFER_SIZE;
+      uschar *newbuffer = store_malloc(newsize);
+      memcpy(newbuffer, big_buffer, *newlen + 1);
+      p = newbuffer  + (p - big_buffer);
+      s = newbuffer  + (s - big_buffer);
+      ss = newbuffer + (ss - big_buffer);
+      t = newbuffer  + (t - big_buffer);
+      big_buffer_size = newsize;
+      store_free(big_buffer);
+      big_buffer = newbuffer;
+      }
+
+    /* Shuffle the remaining characters up or down in the buffer before
+    copying in the replacement text. Don't rescan the replacement for this
+    same macro. */
+
+    pp = p + m->namelen;
+    if ((moveby = m->replen - m->namelen) != 0)
+      {
+      memmove(p + m->replen, pp, (big_buffer + *newlen) - pp + 1);
+      *newlen += moveby;
+      }
+    Ustrncpy(p, m->replacement, m->replen);
+    t = p + m->replen;
+    while (*t && !isupper(*t) && *t != '_') t++;
+    *macro_found = TRUE;
+    }
+  }
+
+/* An empty macro replacement at the start of a line could mean that ss no
+longer points to the first non-blank character. */
+
+while (isspace(*ss)) ss++;
+return ss;
+}
+
 /*************************************************
 *            Read configuration line             *
 *************************************************/
@@ -749,7 +865,6 @@ int startoffset = 0;         /* To first non-blank char in logical line */
 int len = 0;                 /* Of logical line so far */
 int newlen;
 uschar *s, *ss;
-macro_item *m;
 BOOL macro_found;
 
 /* Loop for handling continuation lines, skipping comments, and dealing with
@@ -810,82 +925,7 @@ for (;;)
     newlen += Ustrlen(big_buffer + newlen);
     }
 
-  /* Find the true start of the physical line - leading spaces are always
-  ignored. */
-
-  ss = big_buffer + len;
-  while (isspace(*ss)) ss++;
-
-  /* Process the physical line for macros. If this is the start of the logical
-  line, skip over initial text at the start of the line if it starts with an
-  upper case character followed by a sequence of name characters and an equals
-  sign, because that is the definition of a new macro, and we don't do
-  replacement therein. */
-
-  s = ss;
-  if (len == 0 && isupper(*s))
-    {
-    while (isalnum(*s) || *s == '_') s++;
-    while (isspace(*s)) s++;
-    if (*s != '=') s = ss;          /* Not a macro definition */
-    }
-
-  /* Skip leading chars which cannot start a macro name, to avoid multiple
-  pointless rescans in Ustrstr calls. */
-
-  while (*s && !isupper(*s) && *s != '_') s++;
-
-  /* For each defined macro, scan the line (from after XXX= if present),
-  replacing all occurrences of the macro. */
-
-  macro_found = FALSE;
-  for (m = macros; m; m = m->next)
-    {
-    uschar * p, *pp;
-    uschar * t = s;
-
-    while ((p = Ustrstr(t, m->name)) != NULL)
-      {
-      int moveby;
-
-/* fprintf(stderr, "%s: matched '%s' in '%s'\n", __FUNCTION__, m->name, ss); */
-      /* Expand the buffer if necessary */
-
-      while (newlen - m->namelen + m->replen + 1 > big_buffer_size)
-        {
-        int newsize = big_buffer_size + BIG_BUFFER_SIZE;
-        uschar *newbuffer = store_malloc(newsize);
-        memcpy(newbuffer, big_buffer, newlen + 1);
-        p = newbuffer  + (p - big_buffer);
-        s = newbuffer  + (s - big_buffer);
-        ss = newbuffer + (ss - big_buffer);
-        t = newbuffer  + (t - big_buffer);
-        big_buffer_size = newsize;
-        store_free(big_buffer);
-        big_buffer = newbuffer;
-        }
-
-      /* Shuffle the remaining characters up or down in the buffer before
-      copying in the replacement text. Don't rescan the replacement for this
-      same macro. */
-
-      pp = p + m->namelen;
-      if ((moveby = m->replen - m->namelen) != 0)
-        {
-        memmove(p + m->replen, pp, (big_buffer + newlen) - pp + 1);
-        newlen += moveby;
-        }
-      Ustrncpy(p, m->replacement, m->replen);
-      t = p + m->replen;
-      while (*t && !isupper(*t) && *t != '_') t++;
-      macro_found = TRUE;
-      }
-    }
-
-  /* An empty macro replacement at the start of a line could mean that ss no
-  longer points to the first non-blank character. */
-
-  while (isspace(*ss)) ss++;
+  ss = macros_expand(len, &newlen, &macro_found);
 
   /* Check for comment lines - these are physical lines. */
 
@@ -3277,7 +3317,8 @@ while ((s = get_config_line()))
     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
       "found unexpected BOM (Byte Order Mark)");
 
-  if (isupper(s[0])) read_macro_assignment(s);
+  if (isupper(s[0]))
+    { if (!macro_read_assignment(s)) exim_exit(EXIT_FAILURE, US""); }
 
   else if (Ustrncmp(s, "domainlist", 10) == 0)
     read_named_list(&domainlist_anchor, &domainlist_count,
@@ -3724,7 +3765,7 @@ while ((buffer = get_config_line()) != NULL)
       (d->info->init)(d);
       d = NULL;
       }
-    read_macro_assignment(buffer);
+    if (!macro_read_assignment(buffer)) exim_exit(EXIT_FAILURE, US"");
     continue;
     }
 
@@ -4225,7 +4266,7 @@ between ACLs. */
 
 acl_line = get_config_line();
 
-while(acl_line != NULL)
+while(acl_line)
   {
   uschar name[64];
   tree_node *node;
@@ -4234,7 +4275,7 @@ while(acl_line != NULL)
   p = readconf_readname(name, sizeof(name), acl_line);
   if (isupper(*name) && *p == '=')
     {
-    read_macro_assignment(acl_line);
+    if (!macro_read_assignment(acl_line)) exim_exit(EXIT_FAILURE, US"");
     acl_line = get_config_line();
     continue;
     }
@@ -4278,7 +4319,7 @@ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "local_scan() options not supported: "
 #else
 
 uschar *p;
-while ((p = get_config_line()) != NULL)
+while ((p = get_config_line()))
   {
   (void) readconf_handle_option(p, local_scan_options, local_scan_options_count,
     NULL, US"local_scan option \"%s\" unknown");
@@ -4368,14 +4409,14 @@ while(next_section[0] != 0)
 void
 readconf_save_config(const uschar *s)
 {
-  save_config_line(string_sprintf("# Exim Configuration (%s)",
-    running_in_test_harness ? US"X" : s));
+save_config_line(string_sprintf("# Exim Configuration (%s)",
+  running_in_test_harness ? US"X" : s));
 }
 
 static void
 save_config_position(const uschar *file, int line)
 {
-  save_config_line(string_sprintf("# %d \"%s\"", line, file));
+save_config_line(string_sprintf("# %d \"%s\"", line, file));
 }
 
 /* Append a pre-parsed logical line to the config lines store,
index f4ce584..5d6b611 100644 (file)
@@ -3381,6 +3381,7 @@ while (*filter->pc)
             {
             uschar *mime_body,*reason_end;
             static const uschar nlnl[]="\r\n\r\n";
+           gstring * g;
 
             for
               (
index dd9cea2..27bf708 100644 (file)
@@ -198,7 +198,7 @@ base32d: 32 ${base32d:${base32:32}}
 base32d: 42 ${base32d:${base32:42}}
 base32d error: ABC ${base32d:ABC}
 
-The base62 operator is actually a base36 operator in the Darwin and Cygwin
+the base62 operator is actually a base36 operator in the Darwin and Cygwin
 environments. Write cunning tests that produce the same output in both cases,
 while doing a reasonable check.
 
@@ -531,8 +531,8 @@ abc:   ${lookup{abc}wildlsearch{DIR/aux-var/0002.wild}}
 a.b.c: ${lookup{a.b.c}wildlsearch{DIR/aux-var/0002.wild}}
 ab.c:  ${lookup{ab.c}wildlsearch{DIR/aux-var/0002.wild}}
 xyz:   ${lookup{xyz}wildlsearch{DIR/aux-var/0002.wild}}
-Xyz:   ${lookup{Xyz}wildlsearch{DIR/aux-var/0002.wild}}
-Zyz:   ${lookup{Zyz}wildlsearch{DIR/aux-var/0002.wild}}
+.Xyz:   ${lookup{Xyz}wildlsearch{DIR/aux-var/0002.wild}}
+.Zyz:   ${lookup{Zyz}wildlsearch{DIR/aux-var/0002.wild}}
 a b:   ${lookup{a b}wildlsearch{DIR/aux-var/0002.wild}}
 a  b:  ${lookup{a  b}wildlsearch{DIR/aux-var/0002.wild}}
 a:b:   ${lookup{a:b}wildlsearch{DIR/aux-var/0002.wild}}
@@ -547,8 +547,8 @@ abc:   ${lookup{abc}nwildlsearch{DIR/aux-var/0002.wild}}
 a.b.c: ${lookup{a.b.c}nwildlsearch{DIR/aux-var/0002.wild}}
 ab.c:  ${lookup{ab.c}nwildlsearch{DIR/aux-var/0002.wild}}
 xyz:   ${lookup{xyz}nwildlsearch{DIR/aux-var/0002.wild}}
-Xyz:   ${lookup{Xyz}nwildlsearch{DIR/aux-var/0002.wild}}
-Zyz:   ${lookup{Zyz}nwildlsearch{DIR/aux-var/0002.wild}}
+.Xyz:   ${lookup{Xyz}nwildlsearch{DIR/aux-var/0002.wild}}
+.Zyz:   ${lookup{Zyz}nwildlsearch{DIR/aux-var/0002.wild}}
 a b:   ${lookup{a b}nwildlsearch{DIR/aux-var/0002.wild}}
 a  b:  ${lookup{a  b}nwildlsearch{DIR/aux-var/0002.wild}}
 a:b:   ${lookup{a:b}nwildlsearch{DIR/aux-var/0002.wild}}
@@ -567,10 +567,10 @@ a\\:Xb: ${lookup{a\\:Xb}nwildlsearch{DIR/aux-var/0002.wild}}
 
 # Some tests of case-(in)dependence
 
-MiXeD-CD:  ${lookup{MiXeD-CD}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
-MixeD-CD:  ${lookup{MixeD-CD}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
-MiXeD-Ncd: ${lookup{MiXeD-Ncd}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
-MixeD-Ncd: ${lookup{MixeD-Ncd}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
+.MiXeD-CD:  ${lookup{MiXeD-CD}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
+.MixeD-CD:  ${lookup{MixeD-CD}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
+.MiXeD-Ncd: ${lookup{MiXeD-Ncd}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
+.MixeD-Ncd: ${lookup{MixeD-Ncd}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
 
 # IP address (CIDR) lookups
 
@@ -614,12 +614,12 @@ ${extract{B}{A=1 B=2 C=3}}
 ${extract{ B }{A=1 B=2 C=3}{$value}{NOT FOUND}}
 ${extract{2}{:}{1:2:3}}
 ${extract{ 2 }{:}{1:2:3}{$value}{NOT FOUND}}
-Empty:<${extract{D}{A=1 B=2 C=3}}>
-Empty:<${extract{4}{:}{1:2:3}}>
+empty:<${extract{D}{A=1 B=2 C=3}}>
+empty:<${extract{4}{:}{1:2:3}}>
 ${extract{C}{A=1 B=2 C=3}{<$value>}}
 ${extract{3}{:}{1:2:3}{<$value>}}
-Empty:<${extract{Z}{A=1 B=2 C=3}{<$value>}}>
-Empty:<${extract{4}{:}{1:2:3}{<$value>}}>
+empty:<${extract{Z}{A=1 B=2 C=3}{<$value>}}>
+empty:<${extract{4}{:}{1:2:3}{<$value>}}>
 ${extract{Z}{A=1 B=2 C=3}{<$value>}{no Z}}
 ${extract{4}{:}{1:2:3}{<$value>}{no 4}}
 ${extract{Z}{A=1 B=2 C=3}{<$value>}fail}
@@ -698,8 +698,8 @@ abcdea abc z   ${tr{abcdea}{abc}{z}}
 abcd      ${rfc2047:abcd}
 <:abcd:>  ${rfc2047:<:abcd:>}
 <:ab cd:> ${rfc2047:<:ab cd:>}
-Long:     ${rfc2047: here we go: a string that is going to be encoded: it will go over the 75-char limit}
-Long:     ${rfc2047: here we go: a string that is going to be encoded: it will go over the 75-char limit by a long way; in fact this one will go over the 150 character limit}
+long:     ${rfc2047: here we go: a string that is going to be encoded: it will go over the 75-char limit}
+long:     ${rfc2047: here we go: a string that is going to be encoded: it will go over the 75-char limit by a long way; in fact this one will go over the 150 character limit}
 
 # RFC 2047 decode
 
@@ -739,21 +739,21 @@ ${if exists{/non/exist/file}{${readfile{/non/exist/file}}}{non-exist}}
 # Calling a command
 
 ${run{DIR/aux-fixed/0002.runfile 0}}
-RC=$runrc
+rc=$runrc
 ${run{DIR/aux-fixed/0002.runfile 0}{1}{2}}
-RC=$runrc
+rc=$runrc
 ${run{DIR/aux-fixed/0002.runfile 0}{$value}{2}}
-RC=$runrc
+rc=$runrc
 ${run{DIR/aux-fixed/0002.runfile 1}{$value}{2}}
-RC=$runrc
+rc=$runrc
 ${run{DIR/aux-fixed/0002.runfile 1}{$value}{$value}}
-RC=$runrc
+rc=$runrc
 ${run{DIR/test-nonexist}{Y}{N}}
-RC=$runrc
+rc=$runrc
 >>${run{DIR/bin/iefbr14}}<<
-RC=$runrc
+rc=$runrc
 ${if eq{1}{2}{${run{/non/exist}}}{1!=2}}
-RC=$runrc
+rc=$runrc
 
 # PRVS
 
index 0c6362b..1c8c03b 100644 (file)
@@ -7,13 +7,15 @@ Subject: The subject is not the object
 This is the body of the message. Make the line longer than any header.
 ****
 sudo exim -be -Mset $msg1
-From: $h_from:
-Subject: $h_subject:
+from: $h_from:
+subject: $h_subject:
 message_body_size=$message_body_size
 message_id=$message_id
 message_exim_id=$message_exim_id
 max_received_linelength=$max_received_linelength
 recipients=$recipients
+TESTING_MACROS=$recipients
+(TESTING_MACROS)
 ****
 exim -bs
 mail from:<userz@test.ex>
@@ -29,8 +31,8 @@ This is the body of the message. Make the line much longer than any header.
 quit
 ****
 sudo exim -be -Mset $msg2
-From: $h_from:
-Subject: $h_subject:
+from: $h_from:
+subject: $h_subject:
 message_body_size=$message_body_size
 message_id=$message_id
 message_exim_id=$message_exim_id
index bd4dfcc..2ca0fdd 100644 (file)
@@ -1,11 +1,11 @@
 # crypteq expansions
 
 exim -be
-BadCrypt: ${if crypteq{MySecret}{}{yes}{no}}
-MySecret: ${if crypteq{MySecret}{azrazPWCQJhyg}{yes}{no}}
-MySecret: ${if crypteq{MySecret}{aarazPWCQJhyg}{yes}{no}}
-MySecret: ${if crypteq{MySecret}{\{crypt\}azrazPWCQJhyg}{yes}{no}}
-MySecret: ${if crypteq{MySecret}{\{CRYPT\}zzrazPWCQJhyg}{yes}{no}}
+badCrypt: ${if crypteq{MySecret}{}{yes}{no}}
+mySecret: ${if crypteq{MySecret}{azrazPWCQJhyg}{yes}{no}}
+mySecret: ${if crypteq{MySecret}{aarazPWCQJhyg}{yes}{no}}
+mySecret: ${if crypteq{MySecret}{\{crypt\}azrazPWCQJhyg}{yes}{no}}
+mySecret: ${if crypteq{MySecret}{\{CRYPT\}zzrazPWCQJhyg}{yes}{no}}
 
 crypt16: ${if crypteq{MySecret}{\{crypt16\}azrazPWCQJhyg}{yes}{no}}
 crypt16: ${if crypteq{MySecretRhubarb}{\{crypt\}azrazPWCQJhyg}{yes}{no}}
@@ -26,9 +26,9 @@ abd:  ${if crypteq{abd}{\{sha1\}A9993E364706816ABA3E25717850C26C9CD0D89D}{yes}{n
 
 # Combinations
 
-Y:      ${if and {{crypteq{MySecret}{azrazPWCQJhyg}}{exists{/etc/passwd}}}{Y}{N}}
-Y:      ${if or  {{crypteq{MySecret}{azrazQWCQJhyg}}{exists{/etc/passwd}}}{Y}{N}}
-Y:      ${if or  {{crypteq{MySecret}{azrazPWCQJhyg}}{exists{/etc/pxsswd}}}{Y}{N}}
-N:      ${if or  {{crypteq{MySecret}{azrazQWCQJhyg}}{exists{/etc/pxsswd}}}{Y}{N}}
-N:      ${if and {{crypteq{MySecret}{azrazQWCQJhyg}}{exists{/etc/passwd}}}{Y}{N}}
+y:      ${if and {{crypteq{MySecret}{azrazPWCQJhyg}}{exists{/etc/passwd}}}{Y}{N}}
+y:      ${if or  {{crypteq{MySecret}{azrazQWCQJhyg}}{exists{/etc/passwd}}}{Y}{N}}
+y:      ${if or  {{crypteq{MySecret}{azrazPWCQJhyg}}{exists{/etc/pxsswd}}}{Y}{N}}
+n:      ${if or  {{crypteq{MySecret}{azrazQWCQJhyg}}{exists{/etc/pxsswd}}}{Y}{N}}
+n:      ${if and {{crypteq{MySecret}{azrazQWCQJhyg}}{exists{/etc/passwd}}}{Y}{N}}
 ****
index 81fbae8..b22094c 100644 (file)
@@ -124,13 +124,13 @@ conversion: ${utf8_domain_from_alabel:german.xn--strae-oqa.de}
 imapfolder conversions:
 
 ${imapfolder {Foo/Bar}}
-Foo.Bar
+.  Foo.Bar
 
 ${imapfolder {Foo/Bar} {.} {/}}
-Foo&AC8-Bar
+.  Foo&AC8-Bar
 
 ${imapfolder{Räksmörgås}}
-R&AOQ-ksm&APY-rg&AOU-s
+.  R&AOQ-ksm&APY-rg&AOU-s
 
 
 ****
index 8bf8f88..7f9a509 100644 (file)
@@ -78,9 +78,9 @@ LOG: MAIN PANIC
   ┌considering: no}}
   ├──expanding: no
   └─────result: no
- ├──expanding: match_address:   ${if match_address{a.b.c}{a.b.c}{yes}{no}}
+ ├──expanding: a.b.c
  └─────result: match_address:   no
->>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp (main: expansion test) terminating with rc=0 >>>>>>>>>>>>>>>>
 Exim version x.yz ....
 configuration file is TESTSUITE/test-config
 admin user
@@ -111,7 +111,7 @@ admin user
  ┌considering: -oMt  sender_ident = $sender_ident
  ├──expanding: -oMt  sender_ident = $sender_ident
  └─────result: -oMt  sender_ident = me
->>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp (main: expansion test) terminating with rc=0 >>>>>>>>>>>>>>>>
 1999-03-02 09:44:33 no host name found for IP address V4NET.11.12.13
 Exim version x.yz ....
 configuration file is TESTSUITE/test-config
@@ -171,7 +171,7 @@ sender_rcvhost = ten-1.test.ex ([V4NET.0.0.1] ident=me)
  ┌considering: -oMt  sender_ident = $sender_ident
  ├──expanding: -oMt  sender_ident = $sender_ident
  └─────result: -oMt  sender_ident = me
->>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp (main: expansion test) terminating with rc=0 >>>>>>>>>>>>>>>>
 Exim version x.yz ....
 changed uid/gid: forcing real = effective
   uid=uuuu gid=CALLER_GID pid=pppp
@@ -425,4 +425,4 @@ sender address = CALLER@myhost.test.ex
 1.2.3.4 in "1.2.3"? no (malformed IPv4 address or address mask)
 1.2.3.4 in "1.2.3.4/abc"? no (malformed IPv4 address or address mask)
 search_tidyup called
->>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp (main: expansion test) terminating with rc=0 >>>>>>>>>>>>>>>>
index f51e4e8..996fa2a 100644 (file)
@@ -1,3 +1,3 @@
-LOG: PANIC DIE
+LOG: PANIC
   Exim configuration error in line 10 of TESTSUITE/test-config:
   macro name too long (maximum is 63 characters)
index 0d0d319..12d73e5 100644 (file)
@@ -434,4 +434,4 @@ cached data used for lookup of *.b.c
   in TESTSUITE/aux-fixed/0387.1
 lookup yielded: [*.b.c]
 search_tidyup called
->>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp (main: expansion test) terminating with rc=0 >>>>>>>>>>>>>>>>
index dbf8f66..874ac06 100644 (file)
@@ -129,4 +129,4 @@ cached data used for lookup of root
   in TESTSUITE/aux-fixed/0484.aliases
 lookup yielded: userx
 search_tidyup called
->>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp (main: expansion test) terminating with rc=0 >>>>>>>>>>>>>>>>
index 72aad3d..4b9d87c 100644 (file)
@@ -20,7 +20,7 @@ internal_search_find: file="NULL"
 cached data used for lookup of a=localhost.test.ex
 lookup yielded: 127.0.0.1
 search_tidyup called
->>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp (main: expansion test) terminating with rc=0 >>>>>>>>>>>>>>>>
 Exim version x.yz ....
 configuration file is TESTSUITE/test-config
 admin user
index 1ea0692..cdb2409 100644 (file)
@@ -103,7 +103,7 @@ file lookup required for select * from them where name='it''s';
   in TESTSUITE/aux-fixed/sqlitedb
 lookup yielded: name=it's id=its 
 search_tidyup called
->>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp (main: expansion test) terminating with rc=0 >>>>>>>>>>>>>>>>
 Exim version x.yz ....
 changed uid/gid: forcing real = effective
   uid=uuuu gid=CALLER_GID pid=pppp
@@ -491,4 +491,4 @@ file lookup required for select name from them where id='userx';
   in TESTSUITE/aux-fixed/sqlitedb
 lookup yielded: Ayen Other
 search_tidyup called
->>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp (main: expansion test) terminating with rc=0 >>>>>>>>>>>>>>>>
index 17f48ab..3f8338b 100644 (file)
@@ -41,7 +41,7 @@ LOG: MAIN
   log from Perl
  ├──expanding: ${perl{log_write}{log from Perl}}
  └─────result: Wrote log
->>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp (main: expansion test) terminating with rc=0 >>>>>>>>>>>>>>>>
 LOG: smtp_connection MAIN
   SMTP connection from CALLER
 LOG: MAIN
index 31c81e3..0b6c744 100644 (file)
@@ -133,4 +133,4 @@ cached data used for lookup of root
   in TESTSUITE/aux-fixed/3212.aliases
 lookup yielded: userx
 search_tidyup called
->>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp (main: expansion test) terminating with rc=0 >>>>>>>>>>>>>>>>
index 1422289..c7f8cce 100644 (file)
@@ -189,7 +189,7 @@ newline     tab\134backslash ~tilde\177DEL\200\201.
 > base32d: 42 42
 > Failed: argument for base32d operator is "ABC", which is not a base 32 number
 > 
-> The base62 operator is actually a base36 operator in the Darwin and Cygwin
+> the base62 operator is actually a base36 operator in the Darwin and Cygwin
 > environments. Write cunning tests that produce the same output in both cases,
 > while doing a reasonable check.
 > 
@@ -495,8 +495,8 @@ newline     tab\134backslash ~tilde\177DEL\200\201.
 > a.b.c: *.b.c
 > ab.c:  *b.c
 > xyz:   ^X
-> Xyz:   ^X
-> Zyz:   ^Z
+> .Xyz:   ^X
+> .Zyz:   ^Z
 > a b:   "^a +b"
 > a  b:  "^a +b"
 > a:b:   lookup succeeded
@@ -511,8 +511,8 @@ newline     tab\134backslash ~tilde\177DEL\200\201.
 > a.b.c: *.b.c
 > ab.c:  *b.c
 > xyz:   ^X
-> Xyz:   ^X
-> Zyz:   ^Z
+> .Xyz:   ^X
+> .Zyz:   ^Z
 > a b:   "^a +b"
 > a  b:  "^a +b"
 > a:b:   lookup succeeded
@@ -531,10 +531,10 @@ newline   tab\134backslash ~tilde\177DEL\200\201.
 > 
 > # Some tests of case-(in)dependence
 > 
-> MiXeD-CD:  Data found for case-dependent MiXeD-CD
-> MixeD-CD:  NOT FOUND
-> MiXeD-Ncd: Data found for case-independent MiXeD-nCD
-> MixeD-Ncd: Data found for case-independent MiXeD-nCD
+> .MiXeD-CD:  Data found for case-dependent MiXeD-CD
+> .MixeD-CD:  NOT FOUND
+> .MiXeD-Ncd: Data found for case-independent MiXeD-nCD
+> .MixeD-Ncd: Data found for case-independent MiXeD-nCD
 > 
 > # IP address (CIDR) lookups
 > 
@@ -578,12 +578,12 @@ newline   tab\134backslash ~tilde\177DEL\200\201.
 > 2
 > 2
 > 2
-> Empty:<>
-> Empty:<>
+> empty:<>
+> empty:<>
 > <3>
 > <3>
-> Empty:<>
-> Empty:<>
+> empty:<>
+> empty:<>
 > no Z
 > no 4
 > Failed: "extract" failed and "fail" requested
@@ -662,8 +662,8 @@ newline     tab\134backslash ~tilde\177DEL\200\201.
 > abcd      abcd
 > <:abcd:>  =?iso-8859-8?Q?=3C=3Aabcd=3A=3E?=
 > <:ab cd:> =?iso-8859-8?Q?=3C=3Aab_cd=3A=3E?=
-> Long:     =?iso-8859-8?Q?_here_we_go=3A_a_string_that_is_going_to_be_encoded=3A_?= =?iso-8859-8?Q?it_will_go_over_the_75-char_limit?=
-> Long:     =?iso-8859-8?Q?_here_we_go=3A_a_string_that_is_going_to_be_encoded=3A_?= =?iso-8859-8?Q?it_will_go_over_the_75-char_limit_by_a_long_way=3B_in?= =?iso-8859-8?Q?_fact_this_one_will_go_over_the_150_character_limit?=
+> long:     =?iso-8859-8?Q?_here_we_go=3A_a_string_that_is_going_to_be_encoded=3A_?= =?iso-8859-8?Q?it_will_go_over_the_75-char_limit?=
+> long:     =?iso-8859-8?Q?_here_we_go=3A_a_string_that_is_going_to_be_encoded=3A_?= =?iso-8859-8?Q?it_will_go_over_the_75-char_limit_by_a_long_way=3B_in?= =?iso-8859-8?Q?_fact_this_one_will_go_over_the_150_character_limit?=
 > 
 > # RFC 2047 decode
 > 
@@ -708,25 +708,25 @@ xyz
 > abcd
 1234
 
-> RC=0
+> rc=0
 > 1
-> RC=0
+> rc=0
 > abcd
 1234
 
-> RC=0
+> rc=0
 > 2
-> RC=1
+> rc=1
 > abcd
 1234
 
-> RC=1
+> rc=1
 > N
-> RC=127
+> rc=127
 > >><<
-> RC=0
+> rc=0
 > 1!=2
-> RC=0
+> rc=0
 > 
 > # PRVS
 > 
index ab29dc9..ce255a7 100644 (file)
@@ -1,10 +1,12 @@
-> From: Himself <himself@there.tld>
-> Subject: The subject is not the object
+> from: Himself <himself@there.tld>
+> subject: The subject is not the object
 > message_body_size=71
 > message_id=10HmaX-0005vi-00
 > message_exim_id=10HmaX-0005vi-00
 > max_received_linelength=70
 > recipients=userx@test.x, usery@test.ex
+> Defined macro 'TESTING_MACROS'
+> (userx@test.x, usery@test.ex)
 > 
 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
 250 OK\r
@@ -13,8 +15,8 @@
 354 Enter message, ending with "." on a line by itself\r
 250 OK id=10HmaY-0005vi-00\r
 221 myhost.test.ex closing connection\r
-> From: Himself <himself@there.tld>
-> Subject: The subject is not the object
+> from: Himself <himself@there.tld>
+> subject: The subject is not the object
 > message_body_size=76
 > message_id=10HmaY-0005vi-00
 > message_exim_id=10HmaY-0005vi-00
index 1859bb1..e12e7c3 100644 (file)
@@ -1,8 +1,8 @@
-> BadCrypt: no
-> MySecret: yes
-> MySecret: no
-> MySecret: yes
-> MySecret: no
+> badCrypt: no
+> mySecret: yes
+> mySecret: no
+> mySecret: yes
+> mySecret: no
 > 
 > crypt16: yes
 > crypt16: yes
@@ -23,9 +23,9 @@
 > 
 > # Combinations
 > 
-> Y:      Y
-> Y:      Y
-> Y:      Y
-> N:      N
-> N:      N
+> y:      Y
+> y:      Y
+> y:      Y
+> n:      N
+> n:      N
 > 
index af39676..ac02d8f 100644 (file)
 > imapfolder conversions:
 > 
 > Foo.Bar
-> Foo.Bar
+> .  Foo.Bar
 > 
 > Foo&AC8-Bar
-> Foo&AC8-Bar
+> .  Foo&AC8-Bar
 > 
 > R&AOQ-ksm&APY-rg&AOU-s
-> R&AOQ-ksm&APY-rg&AOU-s
+> .  R&AOQ-ksm&APY-rg&AOU-s
 > 
 > 
 >