Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package exim for openSUSE:Factory checked in 
at 2023-10-16 22:33:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/exim (Old)
 and      /work/SRC/openSUSE:Factory/.exim.new.20540 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "exim"

Mon Oct 16 22:33:24 2023 rev:77 rq:1117952 version:4.96.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/exim/exim.changes        2023-10-02 
20:06:45.559436481 +0200
+++ /work/SRC/openSUSE:Factory/.exim.new.20540/exim.changes     2023-10-16 
22:33:39.961296830 +0200
@@ -1,0 +2,7 @@
+Mon Oct 16 08:45:01 UTC 2023 - Peter Wullinger <wullin...@rz.uni-kiel.de>
+
+- security update to exim 4.96.2
+  * fixes CVE-2023-42117 (bsc#1215787)
+  * fixes CVE-2023-42119 (bsc#1215789)
+
+-------------------------------------------------------------------

Old:
----
  exim-4.96.1.tar.bz2
  exim-4.96.1.tar.bz2.asc

New:
----
  exim-4.96.2.tar.bz2
  exim-4.96.2.tar.bz2.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ exim.spec ++++++
--- /var/tmp/diff_new_pack.Q6FJhI/_old  2023-10-16 22:33:40.965333046 +0200
+++ /var/tmp/diff_new_pack.Q6FJhI/_new  2023-10-16 22:33:40.965333046 +0200
@@ -74,7 +74,7 @@
 %endif
 Requires(pre):  fileutils textutils
 %endif
-Version:        4.96.1
+Version:        4.96.2
 Release:        0
 %if %{with_mysql}
 BuildRequires:  mysql-devel

++++++ exim-4.96.1.tar.bz2 -> exim-4.96.2.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/exim-4.96.1/doc/ChangeLog 
new/exim-4.96.2/doc/ChangeLog
--- old/exim-4.96.1/doc/ChangeLog       2023-09-30 22:52:59.000000000 +0200
+++ new/exim-4.96.2/doc/ChangeLog       2023-10-14 23:55:23.000000000 +0200
@@ -2,6 +2,15 @@
 affect Exim's operation, with an unchanged configuration file.  For new
 options, and new features, see the NewStuff file next to this ChangeLog.
 
+Exim version 4.96.2
+-------------------
+
+JH/01 Bug 3033: Harden dnsdb lookups against crafted DNS responses.
+      CVE-2023-42219
+
+HS/01 Fix string_is_ip_address() CVE-2023-42117 (Bug 3031)
+
+
 Exim version 4.96.1
 -------------------
 
@@ -19,6 +28,10 @@
       be triggered by externally-controlled input.  Found by Trend Micro.
       CVE-2023-42114
 
+JH/04 Bug 2903: avoid exit on an attempt to rewrite a malformed address.
+      Make the rewrite never match and keep the logging.  Trust the
+      admin to be using verify=header-syntax (to actually reject the message).
+
 
 Exim version 4.96
 -----------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/exim-4.96.1/doc/filter.txt 
new/exim-4.96.2/doc/filter.txt
--- old/exim-4.96.1/doc/filter.txt      2023-10-02 12:25:25.000000000 +0200
+++ new/exim-4.96.2/doc/filter.txt      2023-10-15 17:20:38.000000000 +0200
@@ -4,7 +4,7 @@
 
 Copyright (c) 2021 The Exim Maintainers
 
-Revision 4.96.1  02 Oct 2023 PH
+Revision 4.96.2  15 Oct 2023 PH
 
 -------------------------------------------------------------------------------
 
@@ -72,7 +72,7 @@
 
 This document describes the user interfaces to Exim's in-built mail filtering
 facilities, and is copyright (c) The Exim Maintainers 2021. It corresponds to
-Exim version 4.96.1.
+Exim version 4.96.2.
 
 
 1.1 Introduction
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/exim-4.96.1/doc/spec.txt new/exim-4.96.2/doc/spec.txt
--- old/exim-4.96.1/doc/spec.txt        2023-10-02 12:25:25.000000000 +0200
+++ new/exim-4.96.2/doc/spec.txt        2023-10-15 17:20:37.000000000 +0200
@@ -4,7 +4,7 @@
 
 Copyright (c) 2022 The Exim Maintainers
 
-Revision 4.96.1  02 Oct 2023 EM
+Revision 4.96.2  15 Oct 2023 EM
 
 -------------------------------------------------------------------------------
 
@@ -596,7 +596,7 @@
 1.1 Exim documentation
 ----------------------
 
-This edition of the Exim specification applies to version 4.96.1 of Exim.
+This edition of the Exim specification applies to version 4.96.2 of Exim.
 Substantive changes from the 4.95 edition are marked in some renditions of this
 document; this paragraph is so marked if the rendition is capable of showing a
 change indicator.
@@ -1723,7 +1723,7 @@
 
 Exim is distributed as a gzipped or bzipped tar file which, when unpacked,
 creates a directory with the name of the current release (for example,
-exim-4.96.1) into which the following files are placed:
+exim-4.96.2) into which the following files are placed:
 
     ACKNOWLEDGMENTS contains some acknowledgments
     CHANGES         contains a reference to where changes are documented
@@ -2345,7 +2345,7 @@
 For the utility programs, old versions are renamed by adding the suffix .O to
 their names. The Exim binary itself, however, is handled differently. It is
 installed under a name that includes the version number and the compile number,
-for example, exim-4.96.1-1. The script then arranges for a symbolic link called
+for example, exim-4.96.2-1. The script then arranges for a symbolic link called
 exim to point to the binary. If you are updating a previous version of Exim,
 the script takes care to ensure that the name exim is never absent from the
 directory (as seen by other processes).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/exim-4.96.1/src/dns.c new/exim-4.96.2/src/dns.c
--- old/exim-4.96.1/src/dns.c   2023-09-30 22:52:59.000000000 +0200
+++ new/exim-4.96.2/src/dns.c   2023-10-14 23:55:23.000000000 +0200
@@ -304,7 +304,7 @@
 static BOOL
 dnss_inc_aptr(const dns_answer * dnsa, dns_scan * dnss, unsigned delta)
 {
-return (dnss->aptr += delta) >= dnsa->answer + dnsa->answerlen;
+return (dnss->aptr += delta) > dnsa->answer + dnsa->answerlen;
 }
 
 /*************************************************
@@ -388,7 +388,7 @@
       TRACE trace = "A-hdr";
       if (dnss_inc_aptr(dnsa, dnss, namelen+8)) goto null_return;
       GETSHORT(dnss->srr.size, dnss->aptr); /* size of data portion */
-      /* skip over it */
+      /* skip over it, checking for a bogus size */
       TRACE trace = "A-skip";
       if (dnss_inc_aptr(dnsa, dnss, dnss->srr.size)) goto null_return;
       }
@@ -428,10 +428,9 @@
 GETSHORT(dnss->srr.size, dnss->aptr);          /* Size of data portion */
 dnss->srr.data = dnss->aptr;                   /* The record's data follows */
 
-/* Unchecked increment ok here since no further access on this iteration;
-will be checked on next at "R-name". */
-
-dnss->aptr += dnss->srr.size;                  /* Advance to next RR */
+/* skip over it, checking for a bogus size */
+if (dnss_inc_aptr(dnsa, dnss, dnss->srr.size))
+  goto null_return;
 
 /* Return a pointer to the dns_record structure within the dns_answer. This is
 for convenience so that the scans can use nice-looking for loops. */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/exim-4.96.1/src/expand.c new/exim-4.96.2/src/expand.c
--- old/exim-4.96.1/src/expand.c        2023-09-30 22:52:59.000000000 +0200
+++ new/exim-4.96.2/src/expand.c        2023-10-14 23:55:23.000000000 +0200
@@ -2650,9 +2650,17 @@
     case ECOND_ISIP:
     case ECOND_ISIP4:
     case ECOND_ISIP6:
-    rc = string_is_ip_address(sub[0], NULL);
-    *yield = ((cond_type == ECOND_ISIP)? (rc != 0) :
-             (cond_type == ECOND_ISIP4)? (rc == 4) : (rc == 6)) == testfor;
+    {
+      const uschar *errp;
+      const uschar **errpp;
+      DEBUG(D_expand) errpp = &errp; else errpp = 0;
+      if (0 == (rc = string_is_ip_addressX(sub[0], NULL, errpp)))
+        DEBUG(D_expand) debug_printf("failed: %s\n", errp);
+
+      *yield = ( cond_type == ECOND_ISIP  ? rc != 0 :
+                 cond_type == ECOND_ISIP4 ? rc == 4 : rc == 6) == testfor;
+    }
+
     break;
 
     /* Various authentication tests - all optionally compiled */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/exim-4.96.1/src/functions.h 
new/exim-4.96.2/src/functions.h
--- old/exim-4.96.1/src/functions.h     2023-09-30 22:52:59.000000000 +0200
+++ new/exim-4.96.2/src/functions.h     2023-10-14 23:55:23.000000000 +0200
@@ -556,6 +556,7 @@
 extern uschar *string_format_size(int, uschar *);
 extern int     string_interpret_escape(const uschar **);
 extern int     string_is_ip_address(const uschar *, int *);
+extern int     string_is_ip_addressX(const uschar *, int *, const uschar **);
 #ifdef SUPPORT_I18N
 extern BOOL    string_is_utf8(const uschar *);
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/exim-4.96.1/src/lookups/dnsdb.c 
new/exim-4.96.2/src/lookups/dnsdb.c
--- old/exim-4.96.1/src/lookups/dnsdb.c 2023-09-30 22:52:59.000000000 +0200
+++ new/exim-4.96.2/src/lookups/dnsdb.c 2023-10-14 23:55:23.000000000 +0200
@@ -398,43 +398,60 @@
 
       if (type == T_TXT || type == T_SPF)
         {
-        if (outsep2 == NULL)   /* output only the first item of data */
-          yield = string_catn(yield, US (rr->data+1), (rr->data)[0]);
+        if (!outsep2)                  /* output only the first item of data */
+         {
+         uschar n = (rr->data)[0];
+         /* size byte + data bytes must not excced the RRs length */
+         if (n + 1 <= rr->size)
+           yield = string_catn(yield, US (rr->data+1), n);
+         }
         else
           {
           /* output all items */
           int data_offset = 0;
           while (data_offset < rr->size)
             {
-            uschar chunk_len = (rr->data)[data_offset++];
-            if (outsep2[0] != '\0' && data_offset != 1)
+            uschar chunk_len = (rr->data)[data_offset];
+           int remain = rr->size - data_offset;
+
+           /* Apparently there are resolvers that do not check RRs before 
passing
+           them on, and glibc fails to do so.  So every application must...
+           Check for chunk len exceeding RR */
+
+           if (chunk_len > remain)
+             chunk_len = remain;
+
+            if (*outsep2  && data_offset != 0)
               yield = string_catn(yield, outsep2, 1);
-            yield = string_catn(yield, US ((rr->data)+data_offset), chunk_len);
+            yield = string_catn(yield, US ((rr->data) + ++data_offset), 
--chunk_len);
             data_offset += chunk_len;
             }
           }
         }
       else if (type == T_TLSA)
-        {
-        uint8_t usage, selector, matching_type;
-        uint16_t payload_length;
-        uschar s[MAX_TLSA_EXPANDED_SIZE];
-       uschar * sp = s;
-        uschar * p = US rr->data;
-
-        usage = *p++;
-        selector = *p++;
-        matching_type = *p++;
-        /* What's left after removing the first 3 bytes above */
-        payload_length = rr->size - 3;
-        sp += sprintf(CS s, "%d%c%d%c%d%c", usage, *outsep2,
-               selector, *outsep2, matching_type, *outsep2);
-        /* Now append the cert/identifier, one hex char at a time */
-       while (payload_length-- > 0 && sp-s < (MAX_TLSA_EXPANDED_SIZE - 4))
-          sp += sprintf(CS sp, "%02x", *p++);
+       if (rr->size < 3)
+         continue;
+       else
+         {
+         uint8_t usage, selector, matching_type;
+         uint16_t payload_length;
+         uschar s[MAX_TLSA_EXPANDED_SIZE];
+         uschar * sp = s;
+         uschar * p = US rr->data;
+
+         usage = *p++;
+         selector = *p++;
+         matching_type = *p++;
+         /* What's left after removing the first 3 bytes above */
+         payload_length = rr->size - 3;
+         sp += sprintf(CS s, "%d%c%d%c%d%c", usage, *outsep2,
+                 selector, *outsep2, matching_type, *outsep2);
+         /* Now append the cert/identifier, one hex char at a time */
+         while (payload_length-- > 0 && sp-s < (MAX_TLSA_EXPANDED_SIZE - 4))
+           sp += sprintf(CS sp, "%02x", *p++);
 
-        yield = string_cat(yield, s);
-        }
+         yield = string_cat(yield, s);
+         }
       else   /* T_CNAME, T_CSA, T_MX, T_MXH, T_NS, T_PTR, T_SOA, T_SRV */
         {
         int priority, weight, port;
@@ -444,17 +461,20 @@
        switch (type)
          {
          case T_MXH:
+           if (rr->size < sizeof(u_int16_t)) continue;
            /* mxh ignores the priority number and includes only the hostnames 
*/
            GETSHORT(priority, p);
            break;
 
          case T_MX:
+           if (rr->size < sizeof(u_int16_t)) continue;
            GETSHORT(priority, p);
            sprintf(CS s, "%d%c", priority, *outsep2);
            yield = string_cat(yield, s);
            break;
 
          case T_SRV:
+           if (rr->size < 3*sizeof(u_int16_t)) continue;
            GETSHORT(priority, p);
            GETSHORT(weight, p);
            GETSHORT(port, p);
@@ -464,6 +484,7 @@
            break;
 
          case T_CSA:
+           if (rr->size < 3*sizeof(u_int16_t)) continue;
            /* See acl_verify_csa() for more comments about CSA. */
            GETSHORT(priority, p);
            GETSHORT(weight, p);
@@ -514,7 +535,7 @@
 
        if (type == T_SOA && outsep2 != NULL)
          {
-         unsigned long serial, refresh, retry, expire, minimum;
+         unsigned long serial = 0, refresh = 0, retry = 0, expire = 0, minimum 
= 0;
 
          p += rc;
          yield = string_catn(yield, outsep2, 1);
@@ -530,8 +551,11 @@
          else yield = string_cat(yield, s);
 
          p += rc;
-         GETLONG(serial, p); GETLONG(refresh, p);
-         GETLONG(retry,  p); GETLONG(expire,  p); GETLONG(minimum, p);
+         if (rr->size >= p - rr->data - 5*sizeof(u_int32_t))
+           {
+           GETLONG(serial, p); GETLONG(refresh, p);
+           GETLONG(retry,  p); GETLONG(expire,  p); GETLONG(minimum, p);
+           }
          sprintf(CS s, "%c%lu%c%lu%c%lu%c%lu%c%lu",
            *outsep2, serial, *outsep2, refresh,
            *outsep2, retry,  *outsep2, expire,  *outsep2, minimum);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/exim-4.96.1/src/spf.c new/exim-4.96.2/src/spf.c
--- old/exim-4.96.1/src/spf.c   2023-09-30 22:52:59.000000000 +0200
+++ new/exim-4.96.2/src/spf.c   2023-10-14 23:55:23.000000000 +0200
@@ -120,6 +120,7 @@
     switch(rr_type)
       {
       case T_MX:
+       if (rr->size < 2) continue;
        s += 2; /* skip the MX precedence field */
       case T_PTR:
        {
@@ -135,6 +136,7 @@
        gstring * g = NULL;
        uschar chunk_len;
 
+       if (rr->size < 1+6) continue;           /* min for version str */
        if (strncmpic(rr->data+1, US SPF_VER_STR, 6) != 0)
          {
          HDEBUG(D_host_lookup) debug_printf("not an spf record: %.*s\n",
@@ -142,9 +144,12 @@
          continue;
          }
 
-       for (int off = 0; off < rr->size; off += chunk_len)
+       /* require 1 byte for the chunk_len */
+       for (int off = 0; off < rr->size - 1; off += chunk_len)
          {
-         if (!(chunk_len = s[off++])) break;
+         if (  !(chunk_len = s[off++])
+            || rr->size < off + chunk_len      /* ignore bogus size chunks */
+            ) break;
          g = string_catn(g, s+off, chunk_len);
          }
        if (!g)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/exim-4.96.1/src/string.c new/exim-4.96.2/src/string.c
--- old/exim-4.96.1/src/string.c        2023-09-30 22:52:59.000000000 +0200
+++ new/exim-4.96.2/src/string.c        2023-10-14 23:55:23.000000000 +0200
@@ -29,123 +29,133 @@
   maskptr   NULL if no mask is permitted to follow
             otherwise, points to an int where the offset of '/' is placed
             if there is no / followed by trailing digits, *maskptr is set 0
+  errp      NULL if no diagnostic information is required, and if the netmask
+            length should not be checked. Otherwise it is set pointing to a 
short
+            descriptive text.
 
 Returns:    0 if the string is not a textual representation of an IP address
             4 if it is an IPv4 address
             6 if it is an IPv6 address
-*/
 
+The legacy string_is_ip_address() function follows below.
+*/
 int
-string_is_ip_address(const uschar *s, int *maskptr)
-{
-int yield = 4;
-
-/* If an optional mask is permitted, check for it. If found, pass back the
-offset. */
-
-if (maskptr)
+string_is_ip_addressX(const uschar *ip_addr, int *maskptr, const uschar 
**errp) {
+  struct addrinfo hints;
+  struct addrinfo *res;
+
+  uschar *slash, *percent;
+
+  uschar *endp = 0;
+  long int mask = 0;
+  const uschar *addr = 0;
+
+  /* If there is a slash, but we didn't request a (optional) netmask,
+  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, '/'))
   {
-  const uschar *ss = s + Ustrlen(s);
-  *maskptr = 0;
-  if (s != ss && isdigit(*(--ss)))
+    if (!maskptr)
     {
-    while (ss > s && isdigit(ss[-1])) ss--;
-    if (ss > s && *(--ss) == '/') *maskptr = ss - s;
+      if (errp) *errp = "netmask found, but not requested";
+      return 0;
     }
-  }
 
-/* A colon anywhere in the string => IPv6 address */
+    uschar *rest;
+    mask = Ustrtol(slash+1, &rest, 10);
+    if (*rest || mask < 0)
+    {
+      if (errp) *errp = "netmask not numeric or <0";
+      return 0;
+    }
 
-if (Ustrchr(s, ':') != NULL)
+    *maskptr = slash - ip_addr;     /* offset of the slash */
+    endp = slash;
+  } 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
+  family is IPv4, we might reject it.
+  The interface-ID is mutually exclusive with the netmask, to the
+  best of my knowledge. */
+  if (percent = Ustrchr(ip_addr, '%'))
   {
-  BOOL had_double_colon = FALSE;
-  BOOL v4end = FALSE;
-
-  yield = 6;
-
-  /* An IPv6 address must start with hex digit or double colon. A single
-  colon is invalid. */
-
-  if (*s == ':' && *(++s) != ':') return 0;
-
-  /* Now read up to 8 components consisting of up to 4 hex digits each. There
-  may be one and only one appearance of double colon, which implies any number
-  of binary zero bits. The number of preceding components is held in count. */
-
-  for (int count = 0; count < 8; count++)
+    if (slash)
     {
-    /* If the end of the string is reached before reading 8 components, the
-    address is valid provided a double colon has been read. This also applies
-    if we hit the / that introduces a mask or the % that introduces the
-    interface specifier (scope id) of a link-local address. */
-
-    if (*s == 0 || *s == '%' || *s == '/') return had_double_colon ? yield : 0;
-
-    /* If a component starts with an additional colon, we have hit a double
-    colon. This is permitted to appear once only, and counts as at least
-    one component. The final component may be of this form. */
-
-    if (*s == ':')
-      {
-      if (had_double_colon) return 0;
-      had_double_colon = TRUE;
-      s++;
-      continue;
-      }
-
-    /* If the remainder of the string contains a dot but no colons, we
-    can expect a trailing IPv4 address. This is valid if either there has
-    been no double-colon and this is the 7th component (with the IPv4 address
-    being the 7th & 8th components), OR if there has been a double-colon
-    and fewer than 6 components. */
-
-    if (Ustrchr(s, ':') == NULL && Ustrchr(s, '.') != NULL)
-      {
-      if ((!had_double_colon && count != 6) ||
-          (had_double_colon && count > 6)) return 0;
-      v4end = TRUE;
-      yield = 6;
-      break;
-      }
-
-    /* Check for at least one and not more than 4 hex digits for this
-    component. */
-
-    if (!isxdigit(*s++)) return 0;
-    if (isxdigit(*s) && isxdigit(*(++s)) && isxdigit(*(++s))) s++;
-
-    /* If the component is terminated by colon and there is more to
-    follow, skip over the colon. If there is no more to follow the address is
-    invalid. */
-
-    if (*s == ':' && *(++s) == 0) return 0;
+      if (errp) *errp = "interface-ID and netmask are mutually exclusive";
+      return 0;
     }
-
-  /* If about to handle a trailing IPv4 address, drop through. Otherwise
-  all is well if we are at the end of the string or at the mask or at a percent
-  sign, which introduces the interface specifier (scope id) of a link local
-  address. */
-
-  if (!v4end)
-    return (*s == 0 || *s == '%' ||
-           (*s == '/' && maskptr != NULL && *maskptr != 0))? yield : 0;
+    for (uschar *p = percent+1; *p; p++)
+        if (!isalnum(*p) && !ispunct(*p))
+        {
+          if (errp) *errp = "interface-ID must match [[:alnum:][:punct:]]";
+          return 0;
+        }
+    endp = percent;
   }
 
-/* Test for IPv4 address, which may be the tail-end of an IPv6 address. */
+  /* inet_pton() can't parse netmasks and interface IDs, so work on a 
shortened copy
+  allocated on the current stack */
+  if (endp) {
+    ptrdiff_t l = endp - ip_addr;
+    if (l > 255)
+    {
+      if (errp) *errp = "rudiculous long ip address string";
+      return 0;
+    }
+    addr = alloca(l+1); /* *BSD does not have strndupa() */
+    Ustrncpy((uschar *)addr, ip_addr, l);
+    ((uschar*)addr)[l] = '\0';
+  } else addr = ip_addr;
+
+  int af;
+  union { /* we do not need this, but inet_pton() needs a place for storage */
+    struct in_addr sa4;
+    struct in6_addr sa6;
+  } sa;
 
-for (int i = 0; i < 4; i++)
+  af = Ustrchr(addr, ':') ? AF_INET6 : AF_INET;
+  if (!inet_pton(af, addr, &sa))
   {
-  long n;
-  uschar * end;
-
-  if (i != 0 && *s++ != '.') return 0;
-  n = strtol(CCS s, CSS &end, 10);
-  if (n > 255 || n < 0 || end <= s || end > s+3) return 0;
-  s = end;
+    if (errp) *errp = af == AF_INET6 ? "IP address string not parsable as IPv6"
+                                     : "IP address string not parsable IPv4";
+    return 0;
   }
+  /* we do not check the values of the mask here, as
+  this is done on the callers side (but I don't understand why), so
+  actually I'd like to do it here, but it breaks at least 0002 */
+  switch (af)
+  {
+    case AF_INET6:
+        if (errp && mask > 128)
+        {
+          *errp = "IPv6 netmask value must not be >128";
+          return 0;
+        }
+        return 6;
+    case AF_INET:
+        if (percent)
+        {
+          if (errp) *errp = "IPv4 address string must not have an 
interface-ID";
+          return 0;
+        }
+        if (errp && mask > 32) {
+          *errp = "IPv4 netmask value must not be >32";
+          return 0;
+        }
+        return 4;
+    default:
+        if (errp) *errp = "unknown address family (should not happen)";
+        return 0;
+ }
+}
 
-return !*s || (*s == '/' && maskptr && *maskptr != 0) ? yield : 0;
+int
+string_is_ip_address(const uschar *ip_addr, int *maskptr) {
+  return string_is_ip_addressX(ip_addr, maskptr, 0);
 }
+
 #endif  /* COMPILE_UTILITY */
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/exim-4.96.1/src/version.h 
new/exim-4.96.2/src/version.h
--- old/exim-4.96.1/src/version.h       2023-10-02 12:24:59.000000000 +0200
+++ new/exim-4.96.2/src/version.h       2023-10-15 17:20:11.000000000 +0200
@@ -1,5 +1,5 @@
 /* automatically generated file - see ../scripts/reversion */
-#define EXIM_RELEASE_VERSION "4.96.1"
+#define EXIM_RELEASE_VERSION "4.96.2"
 #ifdef EXIM_VARIANT_VERSION
 #define EXIM_VERSION_STR EXIM_RELEASE_VERSION "-" EXIM_VARIANT_VERSION
 #else
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/exim-4.96.1/src/version.sh 
new/exim-4.96.2/src/version.sh
--- old/exim-4.96.1/src/version.sh      2023-10-02 12:24:59.000000000 +0200
+++ new/exim-4.96.2/src/version.sh      2023-10-15 17:20:11.000000000 +0200
@@ -1,3 +1,3 @@
 # automatically generated file - see ../scripts/reversion
-EXIM_RELEASE_VERSION="4.96.1"
+EXIM_RELEASE_VERSION="4.96.2"
 EXIM_COMPILE_NUMBER="1"

Reply via email to