SPDX: Mass-update to GPL-2.0-or-later
[exim.git] / src / src / exim.c
index 47a685aa7b45da1c66fc6402625874b38dd3d1aa..35f4ae4f760773065e50e19270afc3dbf037a2d2 100644 (file)
@@ -5,6 +5,7 @@
 /* Copyright (c) The Exim Maintainers 2020 - 2022 */
 /* Copyright (c) University of Cambridge 1995 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
 
 
 /* The main function: entry point, initialization, and high-level control.
@@ -104,7 +105,9 @@ pcre_gen_mtc_ctx = pcre2_match_context_create(pcre_gen_ctx);
 
 /* This function runs a regular expression match, and sets up the pointers to
 the matched substrings.  The matched strings are copied so the lifetime of
-the subject is not a problem.
+the subject is not a problem.  Matched strings will have the same taint status
+as the subject string (this is not a de-taint method, and must not be made so
+given the support for wildcards in REs).
 
 Arguments:
   re          the compiled expression
@@ -127,16 +130,20 @@ 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;
+    /* Although PCRE2 has a pcre2_substring_get_bynumber() conveneience, it
+    seems to return a bad pointer when a capture group had no data, eg. (.*)
+    matching zero letters.  So use the underlying ovec and hope (!) that the
+    offsets are sane (including that case).  Should we go further and range-
+    check each one vs. the subject string length? */
+    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--;
   }
@@ -242,17 +249,17 @@ void * buf[STACKDUMP_MAX];
 char ** ss;
 int nptrs = backtrace(buf, STACKDUMP_MAX);
 
-log_write(0, LOG_MAIN|LOG_PANIC, "backtrace\n");
-log_write(0, LOG_MAIN|LOG_PANIC, "---\n");
+log_write(0, LOG_MAIN|LOG_PANIC, "backtrace");
+log_write(0, LOG_MAIN|LOG_PANIC, "---");
 if ((ss = backtrace_symbols(buf, nptrs)))
   {
   for (int i = 0; i < nptrs; i++)
-    log_write(0, LOG_MAIN|LOG_PANIC, "\t%s\n", ss[i]);
+    log_write(0, LOG_MAIN|LOG_PANIC, "\t%s", ss[i]);
   free(ss);
   }
 else
-  log_write(0, LOG_MAIN|LOG_PANIC, "backtrace_symbols: %s\n", strerror(errno));
-log_write(0, LOG_MAIN|LOG_PANIC, "---\n");
+  log_write(0, LOG_MAIN|LOG_PANIC, "backtrace_symbols: %s", strerror(errno));
+log_write(0, LOG_MAIN|LOG_PANIC, "---");
 #endif
 }
 #undef STACKDUMP_MAX