Fix ${tr } expansion item. Bug 2533
authorJeremy Harris <jgh146exb@wizmail.org>
Wed, 26 Feb 2020 10:54:56 +0000 (10:54 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Wed, 26 Feb 2020 10:58:22 +0000 (10:58 +0000)
Broken-by: acec9514b1
doc/doc-txt/ChangeLog
src/src/expand.c

index 8f583e21af9b1bc8d1c493c96d0b93f46685c5e4..db06d4930f8016db400785fa021624932799f81b 100644 (file)
@@ -136,6 +136,10 @@ JH/27 Bug 2530: When operating in a timezone with sub-minute offset, such as
       expansion and logging.  Previously, spurious values such as a future
       minute could be seen.
 
+JH/28 Bug 2533: Fix expansion of ${tr } item.  When called in some situations
+      it could crash from a null-deref.  This could also affect the
+      ${addresses: } operator and ${readsock } item.
+
 
 Exim version 4.93
 -----------------
index 9b85c1e0dd582dc2070b99deea67581d67d56219..661959306bbb6d6f0d06c626b0226486a2883dea 100644 (file)
@@ -5291,7 +5291,7 @@ while (*s != 0)
       {
       client_conn_ctx cctx;
       int timeout = 5;
-      int save_ptr = yield->ptr;
+      int save_ptr = gstring_length(yield);
       FILE * fp = NULL;
       uschar * arg;
       uschar * sub_arg[4];
@@ -5524,7 +5524,7 @@ while (*s != 0)
 
         if (sigalrm_seen)
           {
-          yield->ptr = save_ptr;
+          if (yield) yield->ptr = save_ptr;
           expand_string_message = US "socket read timed out";
           goto SOCK_FAIL;
           }
@@ -5691,7 +5691,7 @@ while (*s != 0)
 
     case EITEM_TR:
       {
-      int oldptr = yield->ptr;
+      int oldptr = gstring_length(yield);
       int o2m;
       uschar *sub[3];
 
@@ -6430,7 +6430,7 @@ while (*s != 0)
     case EITEM_REDUCE:
       {
       int sep = 0;
-      int save_ptr = yield->ptr;
+      int save_ptr = gstring_length(yield);
       uschar outsep[2] = { '\0', '\0' };
       const uschar *list, *expr, *temp;
       uschar *save_iterate_item = iterate_item;
@@ -6577,7 +6577,8 @@ while (*s != 0)
         item of the output list, add in a space if the new item begins with the
         separator character, or is an empty string. */
 
-        if (yield->ptr != save_ptr && (temp[0] == *outsep || temp[0] == 0))
+        if (  yield && yield->ptr != save_ptr
+          && (temp[0] == *outsep || temp[0] == 0))
           yield = string_catn(yield, US" ", 1);
 
         /* Add the string in "temp" to the output list that we are building,
@@ -6617,7 +6618,7 @@ while (*s != 0)
       the redundant final separator. Even though an empty item at the end of a
       list does not count, this is tidier. */
 
-      else if (yield->ptr != save_ptr) yield->ptr--;
+      else if (yield && yield->ptr != save_ptr) yield->ptr--;
 
       /* Restore preserved $item */
 
@@ -7549,7 +7550,7 @@ while (*s != 0)
         {
         uschar outsep[2] = { ':', '\0' };
         uschar *address, *error;
-        int save_ptr = yield->ptr;
+        int save_ptr = gstring_length(yield);
         int start, end, domain;  /* Not really used */
 
         while (isspace(*sub)) sub++;
@@ -7580,7 +7581,7 @@ while (*s != 0)
 
           if (address)
             {
-            if (yield->ptr != save_ptr && address[0] == *outsep)
+            if (yield && yield->ptr != save_ptr && address[0] == *outsep)
               yield = string_catn(yield, US" ", 1);
 
             for (;;)
@@ -7609,7 +7610,7 @@ while (*s != 0)
         /* If we have generated anything, remove the redundant final
         separator. */
 
-        if (yield->ptr != save_ptr) yield->ptr--;
+        if (yield && yield->ptr != save_ptr) yield->ptr--;
         f.parse_allow_group = FALSE;
         continue;
         }