From: Jeremy Harris Date: Fri, 11 Nov 2022 18:22:00 +0000 (+0000) Subject: Fix regex substring capture variables for null matches (again). Bug 2933 X-Git-Tag: exim-4.97-RC0~213 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/7ad1a2b2cc57b5f4bcb59186a9a8abcbed9f4f76 Fix regex substring capture variables for null matches (again). Bug 2933 Broken-by: 59d66fdc13f0 --- diff --git a/src/src/exim.c b/src/src/exim.c index 47a685aa7..16c0184e0 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -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--; } diff --git a/src/src/malware.c b/src/src/malware.c index 423a5b692..01dd455ba 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -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 * diff --git a/src/src/regex.c b/src/src/regex.c index b401ba0d7..210620f26 100644 --- a/src/src/regex.c +++ b/src/src/regex.c @@ -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; diff --git a/test/aux-var-src/0383.F b/test/aux-var-src/0383.F index be69ca2c2..59dd0666a 100644 --- a/test/aux-var-src/0383.F +++ b/test/aux-var-src/0383.F @@ -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 diff --git a/test/log/0383 b/test/log/0383 index 7018dd54e..0909b177f 100644 --- a/test/log/0383 +++ b/test/log/0383 @@ -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 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}}" 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 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 T=t1: return message generated +1999-03-02 09:44:33 10HmbB-0005vi-00 ** |TESTSUITE/aux-fixed/showenv "${if inlist {$1}{jab} {$value}}" 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 R=r1 T=t2 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed diff --git a/test/mail/0383.CALLER b/test/mail/0383.CALLER index fb2f4f25c..67bb42f41 100644 --- a/test/mail/0383.CALLER +++ b/test/mail/0383.CALLER @@ -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 diff --git a/test/scripts/0000-Basic/0002 b/test/scripts/0000-Basic/0002 index 898f3b6bc..1efcb2adc 100644 --- a/test/scripts/0000-Basic/0002 +++ b/test/scripts/0000-Basic/0002 @@ -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}} diff --git a/test/stdout/0002 b/test/stdout/0002 index 9232089f6..835d00528 100644 --- a/test/stdout/0002 +++ b/test/stdout/0002 @@ -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