Fix regex substring capture variables for null matches (again). Bug 2933
authorJeremy Harris <jgh146exb@wizmail.org>
Fri, 11 Nov 2022 18:22:00 +0000 (18:22 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Fri, 11 Nov 2022 19:52:19 +0000 (19:52 +0000)
Broken-by: 59d66fdc13f0
src/src/exim.c
src/src/malware.c
src/src/regex.c
test/aux-var-src/0383.F
test/log/0383
test/mail/0383.CALLER
test/scripts/0000-Basic/0002
test/stdout/0002

index 47a685aa7b45da1c66fc6402625874b38dd3d1aa..16c0184e0e5439309093397af9b79956c26a36e1 100644 (file)
@@ -127,16 +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);
-    if (!expand_nstring[expand_nmax])
-      { expand_nstring[expand_nmax] = US""; len = 0; }
-    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--;
   }
index 423a5b692b7dc4a8ed1eb26737f9263a71762826..01dd455ba510158bedb2a5ff50a328b3aefc271b 100644 (file)
@@ -310,16 +310,16 @@ m_pcre_exec(const pcre2_code * cre, uschar * text)
 {
 pcre2_match_data * md = pcre2_match_data_create(2, pcre_gen_ctx);
 int i = pcre2_match(cre, text, PCRE2_ZERO_TERMINATED, 0, 0, md, pcre_gen_mtc_ctx);
-PCRE2_UCHAR * substr = NULL;
-PCRE2_SIZE slen;
+uschar * substr = NULL;
 
 if (i >= 2)                            /* Got it */
   {
-  pcre2_substring_get_bynumber(md, 1, &substr, &slen); /* uses same ctx as md */
-  if (!substr) substr = US"";
+  PCRE2_SIZE * ovec = pcre2_get_ovector_pointer(md);
+  int len = ovec[3] - ovec[2];
+  substr = string_copyn(text + ovec[2], len);
   }
 /* pcre2_match_data_free(md);  gen ctx needs no free */
-return US substr;
+return substr;
 }
 
 static const pcre2_code *
index b401ba0d711d1f23d0b67f219d78ebd6b18d0386..210620f26314ca7c8e23de32d8e1d825fc4e24bd 100644 (file)
@@ -79,10 +79,10 @@ for (pcre_list * ri = re_list_head; ri; ri = ri->next)
 
     for (int nn = 1; nn < n; nn++)
       {
-      PCRE2_UCHAR * cstr;
-      PCRE2_SIZE cslen;
-      pcre2_substring_get_bynumber(md, nn, &cstr, &cslen);     /* uses same ctx as md */
-      regex_vars[nn-1] = cstr ? CUS cstr : CUS"";
+      PCRE2_SIZE * ovec = pcre2_get_ovector_pointer(md);
+      int off = nn * 2;
+      int len = ovec[off + 1] - ovec[off];
+      regex_vars[nn-1] = string_copyn(linebuffer + ovec[off], len);
       }
 
     return OK;
index be69ca2c29f076d2eaaaa76ad19f72f901679752..59dd0666a0f2889a0eee25bba488d2f7fe75ad8e 100644 (file)
@@ -3,7 +3,7 @@
 if error_message then finish endif
 
 if foranyaddress $h_to: ($thisaddress matches "^(alice)") then
-  pipe "DIR/aux-fixed/showenv \"${if match_address {$thisaddress}{alice@test.ex}{$value}}\" $1"
+  pipe "DIR/aux-fixed/showenv \"${if match_address {$thisaddress}{alice@test.ex}{$value}}\" \"${if inlist {$1}{alice} {$value}}\""
   finish
 endif   
 
@@ -13,6 +13,6 @@ if foranyaddress $h_to: ($thisaddress matches "^(marny)") then
 endif   
 
 if $h_to: matches "^(j..)" then
-  pipe "DIR/aux-fixed/showenv $1"
+  pipe "DIR/aux-fixed/showenv \"${if inlist {$1}{jab} {$value}}\""
 endif   
 
index 7018dd54ee4fb351888df4fc4e5f20ea0dfa6bfc..0909b177f6883465117abdab5d23113b35c2d77e 100644 (file)
@@ -1,6 +1,6 @@
 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss for alice
 1999-03-02 09:44:33 10HmaX-0005vi-00 original recipients ignored (system filter)
-1999-03-02 09:44:33 10HmaX-0005vi-00 ** |TESTSUITE/aux-fixed/showenv "${if match_address {$thisaddress}{alice@test.ex}{$value}}" $1 <system-filter> T=t1: return message generated
+1999-03-02 09:44:33 10HmaX-0005vi-00 ** |TESTSUITE/aux-fixed/showenv "${if match_address {$thisaddress}{alice@test.ex}{$value}}" "${if inlist {$1}{alice} {$value}}" <system-filter> T=t1: return message generated
 1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> R=10HmaX-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@test.ex
 1999-03-02 09:44:33 10HmaY-0005vi-00 => CALLER <CALLER@test.ex> R=r1 T=t2
 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
@@ -14,7 +14,7 @@
 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss for jabberwocky
 1999-03-02 09:44:33 10HmbB-0005vi-00 original recipients ignored (system filter)
-1999-03-02 09:44:33 10HmbB-0005vi-00 ** |TESTSUITE/aux-fixed/showenv $1 <system-filter> T=t1: return message generated
+1999-03-02 09:44:33 10HmbB-0005vi-00 ** |TESTSUITE/aux-fixed/showenv "${if inlist {$1}{jab} {$value}}" <system-filter> T=t1: return message generated
 1999-03-02 09:44:33 10HmbC-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@test.ex
 1999-03-02 09:44:33 10HmbC-0005vi-00 => CALLER <CALLER@test.ex> R=r1 T=t2
 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
index fb2f4f25c831351267196b1493d5e40ec9e1a8f0..67bb42f412b1559d285f2da1060836302fad7f4a 100644 (file)
@@ -22,12 +22,12 @@ This message was created automatically by mail delivery software.
 A message that you sent could not be delivered to one or more of its
 recipients. This is a permanent error. The following address(es) failed:
 
-  pipe to |TESTSUITE/aux-fixed/showenv "${if match_address {$thisaddress}{alice@test.ex}{$value}}" $1
+  pipe to |TESTSUITE/aux-fixed/showenv "${if match_address {$thisaddress}{alice@test.ex}{$value}}" "${if inlist {$1}{alice} {$value}}"
     generated by system-filter
 
 The following text was generated during the delivery attempt:
 
------- pipe to |TESTSUITE/aux-fixed/showenv "${if match_address {$thisaddress}{alice@test.ex}{$value}}" $1
+------ pipe to |TESTSUITE/aux-fixed/showenv "${if match_address {$thisaddress}{alice@test.ex}{$value}}" "${if inlist {$1}{alice} {$value}}"
        generated by system-filter ------
 
 Test pipe script
@@ -175,12 +175,12 @@ This message was created automatically by mail delivery software.
 A message that you sent could not be delivered to one or more of its
 recipients. This is a permanent error. The following address(es) failed:
 
-  pipe to |TESTSUITE/aux-fixed/showenv $1
+  pipe to |TESTSUITE/aux-fixed/showenv "${if inlist {$1}{jab} {$value}}"
     generated by system-filter
 
 The following text was generated during the delivery attempt:
 
------- pipe to |TESTSUITE/aux-fixed/showenv $1
+------ pipe to |TESTSUITE/aux-fixed/showenv "${if inlist {$1}{jab} {$value}}"
        generated by system-filter ------
 
 Test pipe script
index 898f3b6bcf1bea9af174d652940a2ab78a346cca..1efcb2adc4af1f2fdc010eb11bc24973298002db 100644 (file)
@@ -467,6 +467,8 @@ match:  ${if match{abcd}{^\N([ab]+)(\w+)$\N}{$2$1}fail}
 match:  ${if match{abcd}{^([ab]+)(\\w+)\$}{$2$1}fail}
 match:  ${if match{wxyz}{^([ab]+)(\\w+)\$}{$2$1}fail}
 match:  ${if match{abcd}{^([ab]+)(\\w+)\$}{$2[${if match{xyz}{(.*)}{$1}fail}]$1}fail}
+# check for empty capture group
+match:  ${if match{abc}{\N^(\S+)\s*(\S.+)*$\N}{<$2>}{}}
 
 match_domain:    ${if match_domain{a.b.c}{x.y.z:a.b.c:p.q.r}{yes}{no}}
 match_domain:    ${if match_domain{a.b.c}{x.y.z:p.q.r}{yes}{no}}
index 9232089f6c4812a0e4344911ed7de92503c2af13..835d00528d9e43242d9987b7b1bf57a7bdd44ab9 100644 (file)
@@ -443,6 +443,8 @@ newline     tab\134backslash ~tilde\177DEL\200\201.
 > match:  cdab
 > Failed: "if" failed and "fail" requested
 > match:  cd[xyz]ab
+> # check for empty capture group
+> match:  <>
 > 
 > match_domain:    yes
 > match_domain:    no