Fix regex substring capture variables for null matches (again). Bug 2933
[exim.git] / src / src / exim.c
index 23e206d2a80867676b23232ed746385b2009ecb1..16c0184e0e5439309093397af9b79956c26a36e1 100644 (file)
@@ -127,14 +127,15 @@ BOOL yield;
 
 if ((yield = (res >= 0)))
   {
+  PCRE2_SIZE * ovec = pcre2_get_ovector_pointer(md);
   res = pcre2_get_ovector_count(md);
   expand_nmax = setup < 0 ? 0 : setup + 1;
   for (int matchnum = setup < 0 ? 0 : 1; matchnum < res; matchnum++)
     {
-    PCRE2_SIZE len;
-    pcre2_substring_get_bynumber(md, matchnum,
-      (PCRE2_UCHAR **)&expand_nstring[expand_nmax], &len);
-    expand_nlength[expand_nmax++] = (int)len;
+    int off = matchnum * 2;
+    int len = ovec[off + 1] - ovec[off];
+    expand_nstring[expand_nmax] = string_copyn(subject + ovec[off], len);
+    expand_nlength[expand_nmax++] = len;
     }
   expand_nmax--;
   }
@@ -232,7 +233,7 @@ exit(1);
 ***********************************************/
 
 #define STACKDUMP_MAX 24
-static void
+void
 stackdump(void)
 {
 #ifndef NO_EXECINFO
@@ -2000,8 +2001,6 @@ regex_whitelisted_macro =
   regex_must_compile(US"^[A-Za-z0-9_/.-]*$", MCS_NOFLAGS, TRUE);
 #endif
 
-for (i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL;
-
 /* If the program is called as "mailq" treat it as equivalent to "exim -bp";
 this seems to be a generally accepted convention, since one finds symbolic
 links called "mailq" in standard OS configurations. */
@@ -3331,7 +3330,7 @@ on the second character (the one after '-'), to save some effort. */
 
        else if (Ustrcmp(argrest, "ai") == 0)
          authenticated_id = string_copy_taint(
-           exim_str_fail_toolong(argv[++i], EXIM_EMAILADDR_MAX, "-oMas"),
+           exim_str_fail_toolong(argv[++i], EXIM_EMAILADDR_MAX, "-oMai"),
            GET_TAINTED);
 
        /* -oMi: Set incoming interface address */
@@ -6083,13 +6082,13 @@ MORELOOP:
   dnslist_domain = dnslist_matched = NULL;
 #ifdef WITH_CONTENT_SCAN
   malware_name = NULL;
+  regex_vars_clear();
 #endif
   callout_address = NULL;
   sending_ip_address = NULL;
   deliver_localpart_data = deliver_domain_data =
   recipient_data = sender_data = NULL;
   acl_var_m = NULL;
-  for(int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL;
 
   store_reset(reset_point);
   }