1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
From 44b6e099b76f403a55e77650821f8a69e9d2682e Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
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 $<n> 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);
|