string.c: do not interpret '\\' before '\0' (CVE-2019-15846)
[exim.git] / src / src / string.c
index 332047460de282a3f0c68d20c577482ec2c981e3..c6549bf933ebcd796a31ece61d8cb5f861de637b 100644 (file)
@@ -224,6 +224,8 @@ interpreted in strings.
 Arguments:
   pp       points a pointer to the initiating "\" in the string;
            the pointer gets updated to point to the final character
+           If the backslash is the last character in the string, it
+           is not interpreted.
 Returns:   the value of the character escape
 */
 
@@ -236,6 +238,7 @@ const uschar *hex_digits= CUS"0123456789abcdef";
 int ch;
 const uschar *p = *pp;
 ch = *(++p);
+if (ch == '\0') return **pp;
 if (isdigit(ch) && ch != '8' && ch != '9')
   {
   ch -= '0';
@@ -905,7 +908,7 @@ int sep = *separator;
 const uschar *s = *listptr;
 BOOL sep_is_special;
 
-if (s == NULL) return NULL;
+if (!s) return NULL;
 
 /* This allows for a fixed specified separator to be an iscntrl() character,
 but at the time of implementation, this is never the case. However, it's best
@@ -921,19 +924,17 @@ if (sep <= 0)
   if (*s == '<' && (ispunct(s[1]) || iscntrl(s[1])))
     {
     sep = s[1];
-    s += 2;
+    if (*++s) ++s;
     while (isspace(*s) && *s != sep) s++;
     }
   else
-    {
-    sep = (sep == 0)? ':' : -sep;
-    }
+    sep = sep ? -sep : ':';
   *separator = sep;
   }
 
 /* An empty string has no list elements */
 
-if (*s == 0) return NULL;
+if (!*s) return NULL;
 
 /* Note whether whether or not the separator is an iscntrl() character. */
 
@@ -944,13 +945,13 @@ sep_is_special = iscntrl(sep);
 if (buffer)
   {
   int p = 0;
-  for (; *s != 0; s++)
+  for (; *s; s++)
     {
     if (*s == sep && (*(++s) != sep || sep_is_special)) break;
     if (p < buflen - 1) buffer[p++] = *s;
     }
   while (p > 0 && isspace(buffer[p-1])) p--;
-  buffer[p] = 0;
+  buffer[p] = '\0';
   }
 
 /* Handle the case when a buffer is not provided. */
@@ -980,10 +981,10 @@ else
 
   for (;;)
     {
-    for (ss = s + 1; *ss != 0 && *ss != sep; ss++) ;
+    for (ss = s + 1; *ss && *ss != sep; ss++) ;
     g = string_catn(g, s, ss-s);
     s = ss;
-    if (*s == 0 || *(++s) != sep || sep_is_special) break;
+    if (!*s || *++s != sep || sep_is_special) break;
     }
   while (g->ptr > 0 && isspace(g->s[g->ptr-1])) g->ptr--;
   buffer = string_from_gstring(g);
@@ -1212,8 +1213,8 @@ memcpy(g->s + p, s, count);
 g->ptr = p + count;
 return g;
 }
+
+
 gstring *
 string_cat(gstring *string, const uschar *s)
 {