From 44b6e099b76f403a55e77650821f8a69e9d2682e Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 3 Dec 2022 23:13:53 +0000 Subject: [PATCH] Fix ${run } arg parsing . Backported by Bryce Harrington for Ubuntu Broken-by: cfe6acff2ddc --- doc/ChangeLog | 4 ++++ src/expand.c | 13 ++++++++++--- src/transport.c | 4 +++- test/scripts/0000-Basic/0002 | 2 ++ test/stdout/0002 | 2 ++ 5 files changed, 21 insertions(+), 4 deletions(-) --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -28,10 +28,14 @@ JH/13 Bug 2929: Fix using $recipients af JH/14 Bug 2933: Fix regex substring match variables for null matches. Since 4.96 a capture group which obtained no text (eg. "(abc)*" matching zero occurrences) could cause a segfault if the corresponding $ was expanded. +JH/15 Fix argument parsing for ${run } expansion. Previously, when an argument + included a close-brace character (eg. it itself used an expansion) an + error occurred. + Exim version 4.96 ----------------- --- a/src/expand.c +++ b/src/expand.c @@ -5529,11 +5529,11 @@ while (*s) { FILE * f; const uschar * arg, ** argv; BOOL late_expand = TRUE; - if ((expand_forbid & RDO_RUN) != 0) + if (expand_forbid & RDO_RUN) { expand_string_message = US"running a command is not permitted"; goto EXPAND_FAILED; } @@ -5561,16 +5561,22 @@ while (*s) } s++; if (late_expand) /* this is the default case */ { - int n = Ustrcspn(s, "}"); + int n; + const uschar * t; + /* Locate the end of the args */ + (void) expand_string_internal(s, TRUE, &t, TRUE, TRUE, NULL); + n = t - s; arg = skipping ? NULL : string_copyn(s, n); s += n; } else { + DEBUG(D_expand) + debug_printf_indent("args string for ${run} expand before split\n"); if (!(arg = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok))) goto EXPAND_FAILED; Uskip_whitespace(&s); } /*{*/ --- a/src/transport.c +++ b/src/transport.c @@ -2187,10 +2187,12 @@ if (expand_arguments) BOOL allow_dollar_recipients = addr && addr->parent && Ustrcmp(addr->parent->address, "system-filter") == 0; for (int i = 0; argv[i]; i++) { + DEBUG(D_expand) debug_printf_indent("arg %d\n", i); + /* Handle special fudge for passing an address list */ if (addr && (Ustrcmp(argv[i], "$pipe_addresses") == 0 || Ustrcmp(argv[i], "${pipe_addresses}") == 0)) @@ -2361,11 +2363,11 @@ if (expand_arguments) } else *errptr = msg; return FALSE; } - if ( f.running_in_test_harness && is_tainted(expanded_arg) + if ( f.running_in_test_harness && is_tainted(expanded_arg) && Ustrcmp(etext, "queryprogram router") == 0) { /* hack, would be good to not need it */ DEBUG(D_transport) debug_printf("SPECIFIC TESTSUITE EXEMPTION: tainted arg '%s'\n", expanded_arg);