[exim-cvs] Logging: ensure that an error for a mistyped IPv6…

Startseite
Nachricht löschen
Nachricht beantworten
Autor: Exim Git Commits Mailing List
Datum:  
To: exim-cvs
Betreff: [exim-cvs] Logging: ensure that an error for a mistyped IPv6 address in a search
Gitweb: https://git.exim.org/exim.git/commitdiff/b0e63c7efdc2133c61545b051042d3617ecd2bbd
Commit:     b0e63c7efdc2133c61545b051042d3617ecd2bbd
Parent:     b677cf473d181346393a357ca8336c223f5cdabe
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Wed Dec 6 19:54:40 2023 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Wed Dec 6 19:54:40 2023 +0000

    Logging: ensure that an error for a mistyped IPv6 address in a search
    list is available for logging.  Bug 3057
---
 doc/doc-docbook/spec.xfpt    |   5 +-
 doc/doc-txt/ChangeLog        |   5 +
 src/src/match.c              |  11 ++-
 src/src/string.c             |   8 +-
 src/src/verify.c             |  24 +++--
 test/confs/0475              |   7 ++
 test/scripts/0000-Basic/0002 | 228 ++++++++++++++++++++++---------------------
 test/scripts/0000-Basic/0475 |   2 +
 test/stderr/0002             |   5 +-
 test/stderr/0475             |  24 ++++-
 test/stdout/0002             |   2 +
 test/stdout/0475             |   2 +
 12 files changed, 193 insertions(+), 130 deletions(-)

diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 6022d7642..dc8f5cc4d 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -39097,7 +39097,7 @@ selection marked by asterisks:
 .irow &`tls_peerdn`&            &nbsp; "TLS peer DN on <= and => lines"
 .irow &`tls_resumption`&        &nbsp; "append * to cipher field"
 .irow &`tls_sni`&            &nbsp; "TLS SNI on <= lines"
-.irow &`unknown_in_list`&        &nbsp; "DNS lookup failed in list match"
+.irow &`unknown_in_list`&        &nbsp; "lookup failed in list match"
 .irow &`all`&                &nbsp; "&*all of the above*&"
 .endtable
 See also the &%slow_lookup_log%& main configuration option,
@@ -39516,7 +39516,8 @@ added to the log line, preceded by SNI=.
 .next
 .cindex "log" "DNS failure in list"
 &%unknown_in_list%&: This setting causes a log entry to be written when the
-result of a list match is failure because a DNS lookup failed.
+result of a list match is failure because a DNS lookup failed, or because
+a bad IP address was in the list.
 .endlist
 
 
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 369e95120..2d82df43d 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -44,6 +44,11 @@ JH/08 Bug 3056: Tighten up parsing of DKIM DNS records.  Previously, whitespace
       Tighten parsing of DKIM header records.  Previously, all but lowercase
       alpha chars would be ignored in potential tag names.
 
+JH/09 Bug 3057: Add heuristic for spotting mistyped IPv6 addresses in lists
+      being searched.  Previously we only had one for IPv4 addresses. Per the
+      documentation, the error results by default in a no-match result for the
+      list.  It is logged if the unknown_in_list log_selector is used.
+
 
 
 Exim version 4.97
diff --git a/src/src/match.c b/src/src/match.c
index df440108e..8b1a3bef6 100644
--- a/src/src/match.c
+++ b/src/src/match.c
@@ -886,14 +886,19 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
       log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
       goto OK_RETURN;
 
-        case ERROR:        /* host name lookup failed - this can only */
-      if (ignore_unknown)    /* be for an incoming host (not outgoing) */
+        /* The ERROR return occurs when checking hosts, when either a forward
+        or reverse lookup has failed. It can also occur in a match_ip list if a
+        non-IP address item is encountered. The error string gives details of
+        which it was. */
+
+        case ERROR:
+      if (ignore_unknown)
         {
         HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_unknown\n",
           error);
         }
       else
-       {
+        {
         HDEBUG(D_lists) debug_printf_indent("%s %s (%s)\n", ot,
           include_unknown? "yes":"no", error);
         (void)fclose(f);
diff --git a/src/src/string.c b/src/src/string.c
index dfe0f2451..3bf2f1df7 100644
--- a/src/src/string.c
+++ b/src/src/string.c
@@ -57,6 +57,7 @@ union { /* we do not need this, but inet_pton() needs a place for storage */
 we return failure, as we do if the mask isn't a pure numerical value,
 or if it is negative. The actual length is checked later, once we know
 the address family. */
+
 if (slash = Ustrchr(ip_addr, '/'))
   {
   uschar * rest;
@@ -74,10 +75,11 @@ if (slash = Ustrchr(ip_addr, '/'))
     return 0;
     }
 
-  *maskptr = slash - ip_addr;     /* offset of the slash */
+  *maskptr = slash - ip_addr;    /* offset of the slash */
   endp = slash;
   }
-else if (maskptr) *maskptr = 0; /* no slash found */
+else if (maskptr)
+  *maskptr = 0;            /* no slash found */
 
 /* The interface-ID suffix (%<id>) is optional (for IPv6). If it
 exists, we check it syntactically. Later, if we know the address
@@ -160,7 +162,7 @@ switch (af)
 int
 string_is_ip_address(const uschar * ip_addr, int * maskptr)
 {
-return string_is_ip_addressX(ip_addr, maskptr, 0);
+return string_is_ip_addressX(ip_addr, maskptr, NULL);
 }
 
 #endif  /* COMPILE_UTILITY */
diff --git a/src/src/verify.c b/src/src/verify.c
index d080ddd63..194e9a76a 100644
--- a/src/src/verify.c
+++ b/src/src/verify.c
@@ -2971,7 +2971,7 @@ if (*ss == '@')
 a (possibly masked) comparison with the current IP address. */
 
 if (string_is_ip_address(ss, &maskoffset) != 0)
-  return (host_is_in_net(cb->host_address, ss, maskoffset)? OK : FAIL);
+  return host_is_in_net(cb->host_address, ss, maskoffset) ? OK : FAIL;
 
 /* The pattern is not an IP address. A common error that people make is to omit
 one component of an IPv4 address, either by accident, or believing that, for
@@ -2982,13 +2982,25 @@ ancient specification.) To aid in debugging these cases, we give a specific
 error if the pattern contains only digits and dots or contains a slash preceded
 only by digits and dots (a slash at the start indicates a file name and of
 course slashes may be present in lookups, but not preceded only by digits and
-dots). */
+dots).  Then the equivalent for IPv6 (roughly). */
 
-for (t = ss; isdigit(*t) || *t == '.'; ) t++;
-if (!*t  || (*t == '/' && t != ss))
+if (Ustrchr(ss, ':'))
   {
-  *error = string_sprintf("malformed IPv4 address or address mask: %.*s", (int)(t - ss), ss);
-  return ERROR;
+  for (t = ss; isxdigit(*t) || *t == ':' || *t == '.'; ) t++;
+  if (!*t  ||  (*t == '/' || *t == '%') && t != ss)
+    {
+    *error = string_sprintf("malformed IPv6 address or address mask: %.*s", (int)(t - ss), ss);
+    return ERROR;
+    }
+  }
+else
+  {
+  for (t = ss; isdigit(*t) || *t == '.'; ) t++;
+  if (!*t  || (*t == '/' && t != ss))
+    {
+    *error = string_sprintf("malformed IPv4 address or address mask: %.*s", (int)(t - ss), ss);
+    return ERROR;
+    }
   }
 
 /* See if there is a semicolon in the pattern, separating a searchtype
diff --git a/test/confs/0475 b/test/confs/0475
index dfca55c78..58eb42052 100644
--- a/test/confs/0475
+++ b/test/confs/0475
@@ -7,6 +7,7 @@
 
 acl_smtp_rcpt = $local_part
 
+log_selector = +unknown_in_list
 
 # ----- ACL -----
 
@@ -18,4 +19,10 @@ a1:
 a2:
   deny hosts = 1.2.3/24
 
+a3:
+  deny hosts = <; fe80::1
+
+a4:
+  deny hosts = <; fe80:1
+
 # End
diff --git a/test/scripts/0000-Basic/0002 b/test/scripts/0000-Basic/0002
index c1fa1bdb5..9b1e5120e 100644
--- a/test/scripts/0000-Basic/0002
+++ b/test/scripts/0000-Basic/0002
@@ -418,7 +418,7 @@ mask:   ${if eq {1}{2}{${mask:invalid}}{NO}}
 5>3m:   ${if >{5 } {3m }{y}{n}}
 5>3z:   ${if >{5 } {3z }{y}{n}}
 5>a:    ${if >{ 5 } {a}{y}{n}}
-5>bad:  ${if >{5 } {${lookup{trick}lsearch{DIR/aux-fixed/0002.lsearch}}} {y}{n}}
+5>bad:  ${if >{5 } {${lookup{trick}lsearch{DIR/aux-fixed/TESTNUM.lsearch}}} {y}{n}}
 

 >0:     ${if > {}{0}{y}{n}}

 =:      ${if = {}{}{y}{n}}
@@ -472,6 +472,7 @@ isip6:  ${if isip6{::1}{y}{n}}      ::1
 isip:   ${if isip {fe80::a00:20ff:fe86:a061}{y}{n}}  fe80::a00:20ff:fe86:a061
 isip4:  ${if isip4{fe80::a00:20ff:fe86:a061}{y}{n}}  fe80::a00:20ff:fe86:a061
 isip6:  ${if isip6{fe80::a00:20ff:fe86:a061}{y}{n}}  fe80::a00:20ff:fe86:a061
+isip6:  ${if isip6{fe80:a00:20ff:fe86:a061}{y}{n}}   fe80:a00:20ff:fe86:a061
 isip:   ${if isip {fe80::1.2.3.4}{y}{n}}  fe80::1.2.3.4
 isip:   ${if isip {rhubarb}{y}{n}}  rhubarb
 isip4:  ${if isip4{rhubarb}{y}{n}}  rhubarb
@@ -527,10 +528,10 @@ match_ip:        08 ${if match_ip{V4NET.11.12.13}{+hlist}}
 match_ip:        09 ${if match_ip{V4NET.11.12.14}{+hlist}}
 match_ip:        10 ${if match_ip{192.168.3.4}{+hlist}}
 match_ip:        11 ${if match_ip{somename}{+hlist}}
-match_ip:        12 ${if match_ip{1.2.3.4}{lsearch;DIR/aux-fixed/0002.matchip}}
-match_ip:        13 ${if match_ip{1.2.3.4}{net-lsearch;DIR/aux-fixed/0002.matchip}}
-match_ip:        14 ${if match_ip{5.6.7.8}{net24-lsearch;DIR/aux-fixed/0002.matchip}}
-match_ip:        15 ${if match_ip{abcd::dcba}{net-iplsearch;DIR/aux-fixed/0002.matchip}}
+match_ip:        12 ${if match_ip{1.2.3.4}{lsearch;DIR/aux-fixed/TESTNUM.matchip}}
+match_ip:        13 ${if match_ip{1.2.3.4}{net-lsearch;DIR/aux-fixed/TESTNUM.matchip}}
+match_ip:        14 ${if match_ip{5.6.7.8}{net24-lsearch;DIR/aux-fixed/TESTNUM.matchip}}
+match_ip:        15 ${if match_ip{abcd::dcba}{net-iplsearch;DIR/aux-fixed/TESTNUM.matchip}}
 
 queue_running:  ${if queue_running{y}{n}}
 first_delivery: ${if first_delivery{y}{n}}
@@ -552,126 +553,126 @@ acl if: ${if acl {{a_defer}{argN}{arg2}} {Y:$value}{N:$value}}
 # Lookups: DIR is the testing directory. In this test we can only use the
 # lookups that are required in all cases.
 
-${lookup{postmaster}lsearch         {DIR/aux-fixed/0002.aliases}{$value}fail}
-${lookup{postmaster}lsearch,ret=full{DIR/aux-fixed/0002.aliases}{$value}fail}
-
-${lookup{x@y}lsearch*@{DIR/aux-fixed/0002.starat}{$value}fail}
-${lookup{x@z}lsearch* {DIR/aux-fixed/0002.starat}{$value}fail}
-${lookup{x@z}lsearch*@{DIR/aux-fixed/0002.starat}{$value}fail}
-${lookup{x@w}lsearch*@{DIR/aux-fixed/0002.starat}{$value}fail}
-
-${lookup{x@y}lsearch*@,ret=full {DIR/aux-fixed/0002.starat}{$value}fail}
-${lookup{x@z}lsearch*,ret=full  {DIR/aux-fixed/0002.starat}{$value}fail}
-${lookup{x@z}lsearch*@,ret=full {DIR/aux-fixed/0002.starat}{$value}fail}
-${lookup{x@w}lsearch*@,ret=full {DIR/aux-fixed/0002.starat}{$value}fail}
-
-${lookup{a.b.c.d}  partial-lsearch {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{x.y.z}    partial-lsearch {DIR/aux-fixed/0002.domains}{$value}{failed x.y.z}}
-${lookup{p.q}      partial-lsearch {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{o.p.q}    partial-lsearch {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{m.n.o.p.q}partial-lsearch {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{x.y.z}    partial1-lsearch{DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{x.y.z}    partial0-lsearch{DIR/aux-fixed/0002.domains}{$value}fail}
-
-${lookup{a.b.c.d}  partial-lsearch,ret=full {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{x.y.z}    partial-lsearch,ret=full {DIR/aux-fixed/0002.domains}{$value}{failed x.y.z}}
-${lookup{p.q}      partial-lsearch,ret=full {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{o.p.q}    partial-lsearch,ret=full {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{m.n.o.p.q}partial-lsearch,ret=full {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{x.y.z}    partial1-lsearch,ret=full{DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{x.y.z}    partial0-lsearch,ret=full{DIR/aux-fixed/0002.domains}{$value}fail}
-
-q1:  ${lookup{abc}        lsearch{DIR/aux-fixed/0002.quoted}}
-q2:  ${lookup{xyz}        lsearch{DIR/aux-fixed/0002.quoted}}
-q3:  ${lookup{pqr}        lsearch{DIR/aux-fixed/0002.quoted}}
-q4:  ${lookup{a:b}        lsearch{DIR/aux-fixed/0002.quoted}}
-q5:  ${lookup{"quoted"}   lsearch{DIR/aux-fixed/0002.quoted}}
-q6:  ${lookup{white space}lsearch{DIR/aux-fixed/0002.quoted}}
-q7:  ${lookup{b\\s}       lsearch{DIR/aux-fixed/0002.quoted}}
-
-q1f: ${lookup{abc}        lsearch,ret=full{DIR/aux-fixed/0002.quoted}}
-q2f: ${lookup{xyz}        lsearch,ret=full{DIR/aux-fixed/0002.quoted}}
-q3f: ${lookup{pqr}        lsearch,ret=full{DIR/aux-fixed/0002.quoted}}
-q4f: ${lookup{a:b}        lsearch,ret=full{DIR/aux-fixed/0002.quoted}}
-q5f: ${lookup{"quoted"}   lsearch,ret=full{DIR/aux-fixed/0002.quoted}}
-q6f: ${lookup{white space}lsearch,ret=full{DIR/aux-fixed/0002.quoted}}
-q7f: ${lookup{b\\s}       lsearch,ret=full{DIR/aux-fixed/0002.quoted}}
-
-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}}
-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}}
-a.b:   ${lookup{a.b}wildlsearch{DIR/aux-var/0002.wild}}
-a..b:  ${lookup{a..b}wildlsearch{DIR/aux-var/0002.wild}}
-a9b:   ${lookup{a9b}wildlsearch{DIR/aux-var/0002.wild}}
-a99b:  ${lookup{a99b}wildlsearch{DIR/aux-var/0002.wild}}
+${lookup{postmaster}lsearch         {DIR/aux-fixed/TESTNUM.aliases}{$value}fail}
+${lookup{postmaster}lsearch,ret=full{DIR/aux-fixed/TESTNUM.aliases}{$value}fail}
+
+${lookup{x@y}lsearch*@{DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+${lookup{x@z}lsearch* {DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+${lookup{x@z}lsearch*@{DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+${lookup{x@w}lsearch*@{DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+
+${lookup{x@y}lsearch*@,ret=full {DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+${lookup{x@z}lsearch*,ret=full  {DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+${lookup{x@z}lsearch*@,ret=full {DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+${lookup{x@w}lsearch*@,ret=full {DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+
+${lookup{a.b.c.d}  partial-lsearch {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{x.y.z}    partial-lsearch {DIR/aux-fixed/TESTNUM.domains}{$value}{failed x.y.z}}
+${lookup{p.q}      partial-lsearch {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{o.p.q}    partial-lsearch {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{m.n.o.p.q}partial-lsearch {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{x.y.z}    partial1-lsearch{DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{x.y.z}    partial0-lsearch{DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+
+${lookup{a.b.c.d}  partial-lsearch,ret=full {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{x.y.z}    partial-lsearch,ret=full {DIR/aux-fixed/TESTNUM.domains}{$value}{failed x.y.z}}
+${lookup{p.q}      partial-lsearch,ret=full {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{o.p.q}    partial-lsearch,ret=full {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{m.n.o.p.q}partial-lsearch,ret=full {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{x.y.z}    partial1-lsearch,ret=full{DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{x.y.z}    partial0-lsearch,ret=full{DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+
+q1:  ${lookup{abc}        lsearch{DIR/aux-fixed/TESTNUM.quoted}}
+q2:  ${lookup{xyz}        lsearch{DIR/aux-fixed/TESTNUM.quoted}}
+q3:  ${lookup{pqr}        lsearch{DIR/aux-fixed/TESTNUM.quoted}}
+q4:  ${lookup{a:b}        lsearch{DIR/aux-fixed/TESTNUM.quoted}}
+q5:  ${lookup{"quoted"}   lsearch{DIR/aux-fixed/TESTNUM.quoted}}
+q6:  ${lookup{white space}lsearch{DIR/aux-fixed/TESTNUM.quoted}}
+q7:  ${lookup{b\\s}       lsearch{DIR/aux-fixed/TESTNUM.quoted}}
+
+q1f: ${lookup{abc}        lsearch,ret=full{DIR/aux-fixed/TESTNUM.quoted}}
+q2f: ${lookup{xyz}        lsearch,ret=full{DIR/aux-fixed/TESTNUM.quoted}}
+q3f: ${lookup{pqr}        lsearch,ret=full{DIR/aux-fixed/TESTNUM.quoted}}
+q4f: ${lookup{a:b}        lsearch,ret=full{DIR/aux-fixed/TESTNUM.quoted}}
+q5f: ${lookup{"quoted"}   lsearch,ret=full{DIR/aux-fixed/TESTNUM.quoted}}
+q6f: ${lookup{white space}lsearch,ret=full{DIR/aux-fixed/TESTNUM.quoted}}
+q7f: ${lookup{b\\s}       lsearch,ret=full{DIR/aux-fixed/TESTNUM.quoted}}
+
+abc:   ${lookup{abc}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a.b.c: ${lookup{a.b.c}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+ab.c:  ${lookup{ab.c}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+xyz:   ${lookup{xyz}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+.Xyz:   ${lookup{Xyz}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+.Zyz:   ${lookup{Zyz}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a b:   ${lookup{a b}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a  b:  ${lookup{a  b}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a:b:   ${lookup{a:b}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a.b:   ${lookup{a.b}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a..b:  ${lookup{a..b}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a9b:   ${lookup{a9b}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a99b:  ${lookup{a99b}wildlsearch{DIR/aux-var/TESTNUM.wild}}
 
 # Should give the same results as above because expansion does nothing
 
-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}}
-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}}
+abc:   ${lookup{abc}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+a.b.c: ${lookup{a.b.c}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+ab.c:  ${lookup{ab.c}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+xyz:   ${lookup{xyz}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+.Xyz:   ${lookup{Xyz}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+.Zyz:   ${lookup{Zyz}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+a b:   ${lookup{a b}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+a  b:  ${lookup{a  b}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+a:b:   ${lookup{a:b}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
 
 # Should fail because of no expansion
 
-a.b:   ${lookup{a.b}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NO}}
-a..b:  ${lookup{a..b}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NO}}
-a9b:   ${lookup{a9b}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NO}}
-a99b:  ${lookup{a99b}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NO}}
+a.b:   ${lookup{a.b}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NO}}
+a..b:  ${lookup{a..b}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NO}}
+a9b:   ${lookup{a9b}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NO}}
+a99b:  ${lookup{a99b}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NO}}
 
 # But these should succeed
 
-a\\:b:  ${lookup{a\\:b}nwildlsearch{DIR/aux-var/0002.wild}}
-a\\:Xb: ${lookup{a\\:Xb}nwildlsearch{DIR/aux-var/0002.wild}}
+a\\:b:  ${lookup{a\\:b}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+a\\:Xb: ${lookup{a\\:Xb}nwildlsearch{DIR/aux-var/TESTNUM.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/TESTNUM.wild}{$value}{NOT FOUND}}
+.MixeD-CD:  ${lookup{MixeD-CD}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NOT FOUND}}
+.MiXeD-Ncd: ${lookup{MiXeD-Ncd}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NOT FOUND}}
+.MixeD-Ncd: ${lookup{MixeD-Ncd}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NOT FOUND}}
 
 # IP address (CIDR) lookups
 
-1.2.3.4:      ${lookup{1.2.3.4}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-1.2.3.5:      ${lookup{1.2.3.5}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-1.2.3.5:      ${lookup{1.2.3.5}iplsearch*{DIR/aux-fixed/0002.iplsearch}}
-abcd::cdab:   ${lookup{abcd::cdab}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-192.168.1.2:  ${lookup{192.168.1.2}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-192.168.5.6:  ${lookup{192.168.5.6}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-abcd:abcd::   ${lookup{abcd:abcd::}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-abcd:abcd:1:: ${lookup{abcd:abcd:1::}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-abcd:abcd::3  ${lookup{abcd:abcd::3}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-rhubarb       ${lookup{rhubarb}iplsearch{DIR/aux-fixed/0002.iplsearch}}
+1.2.3.4:      ${lookup{1.2.3.4}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+1.2.3.5:      ${lookup{1.2.3.5}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+1.2.3.5:      ${lookup{1.2.3.5}iplsearch*{DIR/aux-fixed/TESTNUM.iplsearch}}
+abcd::cdab:   ${lookup{abcd::cdab}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+192.168.1.2:  ${lookup{192.168.1.2}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+192.168.5.6:  ${lookup{192.168.5.6}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+abcd:abcd::   ${lookup{abcd:abcd::}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+abcd:abcd:1:: ${lookup{abcd:abcd:1::}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+abcd:abcd::3  ${lookup{abcd:abcd::3}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+rhubarb       ${lookup{rhubarb}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
 
 
 # Nested Lookups - style 1
 
-${lookup{${lookup{key1}lsearch{DIR/aux-fixed/0002.rec}{$value}{key1f}}}lsearch{DIR/aux-fixed/0002.rec}{$value}fail}
-${lookup{${lookup{key3}lsearch{DIR/aux-fixed/0002.rec}{$value}{key1f}}}lsearch{DIR/aux-fixed/0002.rec}{$value}fail}
+${lookup{${lookup{key1}lsearch{DIR/aux-fixed/TESTNUM.rec}{$value}{key1f}}}lsearch{DIR/aux-fixed/TESTNUM.rec}{$value}fail}
+${lookup{${lookup{key3}lsearch{DIR/aux-fixed/TESTNUM.rec}{$value}{key1f}}}lsearch{DIR/aux-fixed/TESTNUM.rec}{$value}fail}
 
 # Nested Lookups - style 2
 
-${lookup{key1}lsearch{DIR/aux-fixed/0002.rec}{${lookup{$value}lsearch{DIR/aux-fixed/0002.rec}{$value}{failed for $value}}}{failed for key1}}
-${lookup{key3}lsearch{DIR/aux-fixed/0002.rec}{${lookup{$value}lsearch{DIR/aux-fixed/0002.rec}{$value}{failed for $value}}}{failed for key1}}
+${lookup{key1}lsearch{DIR/aux-fixed/TESTNUM.rec}{${lookup{$value}lsearch{DIR/aux-fixed/TESTNUM.rec}{$value}{failed for $value}}}{failed for key1}}
+${lookup{key3}lsearch{DIR/aux-fixed/TESTNUM.rec}{${lookup{$value}lsearch{DIR/aux-fixed/TESTNUM.rec}{$value}{failed for $value}}}{failed for key1}}
 
 # Other nesting tests
 
-${lookup{one}lsearch{DIR/aux-fixed/0002.alias1}{$value${lookup{one}lsearch{DIR/aux-fixed/0002.alias2}{,$value}}}{${lookup{one}lsearch{DIR/aux-fixed/0002.alias2}{$value}fail}}}
-${lookup{two}lsearch{DIR/aux-fixed/0002.alias1}{$value${lookup{two}lsearch{DIR/aux-fixed/0002.alias2}{,$value}}}{${lookup{two}lsearch{DIR/aux-fixed/0002.alias2}{$value}fail}}}
-${lookup{both}lsearch{DIR/aux-fixed/0002.alias1}{$value${lookup{both}lsearch{DIR/aux-fixed/0002.alias2}{,$value}}}{${lookup{both}lsearch{DIR/aux-fixed/0002.alias2}{$value}fail}}}
-${lookup{neither}lsearch{DIR/aux-fixed/0002.alias1}{$value${lookup{neither}lsearch{DIR/aux-fixed/0002.alias2}{,$value}}}{${lookup{neither}lsearch{DIR/aux-fixed/0002.alias2}{$value}fail}}}
+${lookup{one}lsearch{DIR/aux-fixed/TESTNUM.alias1}{$value${lookup{one}lsearch{DIR/aux-fixed/TESTNUM.alias2}{,$value}}}{${lookup{one}lsearch{DIR/aux-fixed/TESTNUM.alias2}{$value}fail}}}
+${lookup{two}lsearch{DIR/aux-fixed/TESTNUM.alias1}{$value${lookup{two}lsearch{DIR/aux-fixed/TESTNUM.alias2}{,$value}}}{${lookup{two}lsearch{DIR/aux-fixed/TESTNUM.alias2}{$value}fail}}}
+${lookup{both}lsearch{DIR/aux-fixed/TESTNUM.alias1}{$value${lookup{both}lsearch{DIR/aux-fixed/TESTNUM.alias2}{,$value}}}{${lookup{both}lsearch{DIR/aux-fixed/TESTNUM.alias2}{$value}fail}}}
+${lookup{neither}lsearch{DIR/aux-fixed/TESTNUM.alias1}{$value${lookup{neither}lsearch{DIR/aux-fixed/TESTNUM.alias2}{,$value}}}{${lookup{neither}lsearch{DIR/aux-fixed/TESTNUM.alias2}{$value}fail}}}
 
 # Lookup quotes for standardly expected lookups
 
@@ -798,26 +799,26 @@ toobig    ${from_utf8:aĀd}
 # File insertion
 
 ${readfile}
-${readfile{DIR/aux-fixed/0002.readfile}}
-${readfile{DIR/aux-fixed/0002.readfile}{}}
-${readfile{DIR/aux-fixed/0002.readfile}{:}}
-${readfile{DIR/aux-fixed/0002.readfile}{ - }}
+${readfile{DIR/aux-fixed/TESTNUM.readfile}}
+${readfile{DIR/aux-fixed/TESTNUM.readfile}{}}
+${readfile{DIR/aux-fixed/TESTNUM.readfile}{:}}
+${readfile{DIR/aux-fixed/TESTNUM.readfile}{ - }}
 ${readfile{/non/exist/file}}
 ${if exists{/non/exist/file}{${readfile{/non/exist/file}}}{non-exist}}
->${readfile{DIR/aux-fixed/0002.readfile}{!}}\
+>${readfile{DIR/aux-fixed/TESTNUM.readfile}{!}}\
     <
 
 # Calling a command
 
-${run{DIR/aux-fixed/0002.runfile 0}}
+${run{DIR/aux-fixed/TESTNUM.runfile 0}}
 rc=$runrc
-${run{DIR/aux-fixed/0002.runfile 0}{1}{2}}
+${run{DIR/aux-fixed/TESTNUM.runfile 0}{1}{2}}
 rc=$runrc
-${run{DIR/aux-fixed/0002.runfile 0}{$value}{2}}
+${run{DIR/aux-fixed/TESTNUM.runfile 0}{$value}{2}}
 rc=$runrc
-${run{DIR/aux-fixed/0002.runfile 1}{$value}{2}}
+${run{DIR/aux-fixed/TESTNUM.runfile 1}{$value}{2}}
 rc=$runrc
-${run{DIR/aux-fixed/0002.runfile 1}{$value}{$value}}
+${run{DIR/aux-fixed/TESTNUM.runfile 1}{$value}{$value}}
 rc=$runrc
 ${run{DIR/test-nonexist}{Y}{N}}
 rc=$runrc
@@ -825,9 +826,9 @@ rc=$runrc
 rc=$runrc
 ${if eq{1}{2}{${run{/non/exist}}}{1!=2}}
 rc=$runrc
-${run,preexpand {DIR/aux-fixed/0002.runfile 0}}
+${run,preexpand {DIR/aux-fixed/TESTNUM.runfile 0}}
 rc=$runrc
-${run{DIR/aux-fixed/0002.runfile ${quote:1}}{$value}{2}}
+${run{DIR/aux-fixed/TESTNUM.runfile ${quote:1}}{$value}{2}}
 rc=$runrc
 
 # PRVS
@@ -1138,10 +1139,11 @@ Subject: =?iso-8859-8?Q?_here_we_go=3A_a_string_that_is_going_to_be_encoded=3A_i
 .
 quit
 ****
-# Certain kind of error
+# Bad IP addresses
 exim -d -be
 match_ip:        15 ${if match_ip{1.2.3.4}{1.2.3}}
 match_ip:        16 ${if match_ip{1.2.3.4}{1.2.3.4/abc}}
+match_ip:        17 ${if match_ip{::1}{<; aaaa:bbbb}}
 ****
 # Operation of inlist and negated inlist
 exim -be
diff --git a/test/scripts/0000-Basic/0475 b/test/scripts/0000-Basic/0475
index 5008c8768..05f3a70e4 100644
--- a/test/scripts/0000-Basic/0475
+++ b/test/scripts/0000-Basic/0475
@@ -4,5 +4,7 @@ helo test
 mail from:<>
 rcpt to:<a1@b>
 rcpt to:<a2@b>
+rcpt to:<a3@b>
+rcpt to:<a4@b>
 quit
 ****
diff --git a/test/stderr/0002 b/test/stderr/0002
index a74e98c11..087b58f60 100644
--- a/test/stderr/0002
+++ b/test/stderr/0002
@@ -746,5 +746,8 @@ sender address = CALLER@???
   1.2.3.4 in "1.2.3.4/abc"?
    list element: 1.2.3.4/abc
    1.2.3.4 in "1.2.3.4/abc"? no (malformed IPv4 address or address mask: 1.2.3.4)
-  search_tidyup called
+   ::1 in "<; aaaa:bbbb"?
+   ╎list element: aaaa:bbbb
+   ╎::1 in "<; aaaa:bbbb"? no (malformed IPv6 address or address mask: aaaa:bbbb)
+   search_tidyup called

>>>>>>>>>>>>>>>> Exim pid=p1240 (fresh-exec) terminating with rc=0 >>>>>>>>>>>>>>>>

diff --git a/test/stderr/0475 b/test/stderr/0475
index 4626506f5..f080bfc0e 100644
--- a/test/stderr/0475
+++ b/test/stderr/0475
@@ -11,7 +11,7 @@
>>> list element: @[]
>>> test in helo_lookup_domains? no (end of list)
>>> using ACL "a1"

->>> processing "deny" (TESTSUITE/test-config 16)
+>>> processing "deny" (TESTSUITE/test-config 17)
>>> check hosts = 1.2.3.4 : <; 1.2.3.4::5.6.7.8
>>> host in "1.2.3.4 : <; 1.2.3.4::5.6.7.8"?
>>> list element: 1.2.3.4

@@ -21,11 +21,31 @@ LOG: unknown lookup type "<" in host list item "<; 1.2.3.4:5.6.7.8"
>>> deny: condition test deferred in ACL "a1"

LOG: H=(test) [V4NET.0.0.0] F=<> temporarily rejected RCPT <a1@b>: unknown lookup type "<"
>>> using ACL "a2"

->>> processing "deny" (TESTSUITE/test-config 19)
+>>> processing "deny" (TESTSUITE/test-config 20)
>>> check hosts = 1.2.3/24
>>> host in "1.2.3/24"?
>>> list element: 1.2.3/24
>>> host in "1.2.3/24"? no (malformed IPv4 address or address mask: 1.2.3)

+LOG: list matching forced to fail: malformed IPv4 address or address mask: 1.2.3
>>> deny: condition test failed in ACL "a2"
>>> end of ACL "a2": implicit DENY

 LOG: H=(test) [V4NET.0.0.0] F=<> rejected RCPT <a2@b>
+>>>  using ACL "a3"
+>>>  processing "deny" (TESTSUITE/test-config 23)
+>>>  check hosts = <; fe80::1
+>>>  host in "<; fe80::1"?
+>>>   list element: fe80::1
+>>>  host in "<; fe80::1"? no (end of list)
+>>>  deny: condition test failed in ACL "a3"
+>>>  end of ACL "a3": implicit DENY
+LOG: H=(test) [V4NET.0.0.0] F=<> rejected RCPT <a3@b>
+>>>  using ACL "a4"
+>>>  processing "deny" (TESTSUITE/test-config 26)
+>>>  check hosts = <; fe80:1
+>>>  host in "<; fe80:1"?
+>>>   list element: fe80:1
+>>>   host in "<; fe80:1"? no (malformed IPv6 address or address mask: fe80:1)
+LOG: list matching forced to fail: malformed IPv6 address or address mask: fe80:1
+>>>   deny: condition test failed in ACL "a4"
+>>>   end of ACL "a4": implicit DENY
+LOG: H=(test) [V4NET.0.0.0] F=<> rejected RCPT <a4@b>
diff --git a/test/stdout/0002 b/test/stdout/0002
index d5bb0605c..a79a5c733 100644
--- a/test/stdout/0002
+++ b/test/stdout/0002
@@ -466,6 +466,7 @@ newline    tab\134backslash ~tilde\177DEL\200\201.

> isip: y fe80::a00:20ff:fe86:a061
> isip4: n fe80::a00:20ff:fe86:a061
> isip6: y fe80::a00:20ff:fe86:a061

+> isip6: n fe80:a00:20ff:fe86:a061
> isip: y fe80::1.2.3.4
> isip: n rhubarb
> isip4: n rhubarb

@@ -1091,6 +1092,7 @@ xyz
221 myhost.test.ex closing connection
 > match_ip:        15 
 > match_ip:        16 

+> match_ip:        17 

>
> in list
> in list

diff --git a/test/stdout/0475 b/test/stdout/0475
index 819cea3bc..d1f718997 100644
--- a/test/stdout/0475
+++ b/test/stdout/0475
@@ -8,4 +8,6 @@
250 OK
451 Temporary local problem - please try later
550 Administrative prohibition
+550 Administrative prohibition
+550 Administrative prohibition
221 the.local.host.name closing connection

--
## subscription configuration (requires account):
## https://lists.exim.org/mailman3/postorius/lists/exim-cvs.lists.exim.org/
## unsubscribe (doesn't require an account):
## exim-cvs-unsubscribe@???
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/