Gitweb:
https://git.exim.org/exim.git/commitdiff/1efe178fac47bb1fa7dbacc46c1871553b7e85a4
Commit: 1efe178fac47bb1fa7dbacc46c1871553b7e85a4
Parent: 76257a8277319084720d800af285b7fde16e9fbb
Author: Jeremy Harris <jgh146exb@???>
AuthorDate: Wed Dec 18 14:12:12 2024 +0000
Committer: Jeremy Harris <jgh146exb@???>
CommitDate: Wed Dec 18 14:12:12 2024 +0000
Cutthrough: support a transport dkim_domain that expands to empty
---
doc/doc-docbook/spec.xfpt | 4 ++++
src/Makefile | 9 +++++++--
src/src/expand.c | 33 ++++++++++++++++++++++++++-------
src/src/functions.h | 1 +
src/src/verify.c | 12 +++++++-----
5 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 31aafa4be..d4e0d6d4f 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -170,6 +170,8 @@
. --- ID that ties them together.
. --- The index entry points to the most-recent chapter head, section or subsection
. --- head, or list-item.
+. ---- It'd be a lot nicer to point to the precise word-location; a chapter
+. ---- can be pretty big.
.macro cindex
&<indexterm role="concept">&
@@ -1269,6 +1271,8 @@ one of the checks to be performed in an ACL for incoming messages, on both
sender and recipient addresses, and it can be tested using the &%-bv%& and
&%-bvs%& command line options.
+.cindex router "verify mode"
+.cindex "verify mode" routers
When an address is being verified, the routers are run in &"verify mode"&. This
does not affect the way the routers work, but it is a state that can be
detected. By this means, a router can be skipped or made to behave differently
diff --git a/src/Makefile b/src/Makefile
index a6e0de9f4..5e82de271 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -102,12 +102,17 @@ clean_exim:; cd build-$(buildname); \
done; \
$(RM_COMMAND) -fr dynmodules
-clean: clean_exim
+clean-doc: FRC
+ cd ../doc/doc-docbook; \
+ $(RM_COMMAND) {filter,spec}*.{pdf,ps,txt,html,xml}
+
+clean: clean_exim clean_doc
@echo ""; echo '*** "make clean" just removes all .o and .a files'
@echo '*** Use "make makefile" to force a rebuild of the makefile'
@echo ""
-distclean:; $(RM_COMMAND) -rf build-* cscope*
+distclean: clean_doc
+ $(RM_COMMAND) -rf build-* cscope*
cscope.files: FRC
echo "-q" > $@
diff --git a/src/src/expand.c b/src/src/expand.c
index b290720aa..31420d59f 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -4601,13 +4601,14 @@ and, given the acl condition, ${if }. This is an unfortunate consequence of
string expansion becoming too powerful.
Arguments:
- string the string to be expanded
+ s the string to be expanded
flags
brace_ends expansion is to stop at }
honour_dollar TRUE if $ is to be expanded,
FALSE if it's just another character
skipping TRUE for recursive calls when the value isn't actually going
to be used (to allow for optimisation)
+ exists_only return as soon as we have a char, for optimisation
left if not NULL, a pointer to the first character after the
expansion is placed here (typically used with brace_ends)
resetok_p if not NULL, pointer to flag - write FALSE if unsafe to reset
@@ -4621,13 +4622,13 @@ Returns: NULL if expansion fails:
*/
static uschar *
-expand_string_internal(const uschar * string, esi_flags flags, const uschar ** left,
+expand_string_internal(const uschar * s, esi_flags flags, const uschar ** left,
BOOL *resetok_p, BOOL * textonly_p)
{
rmark reset_point = store_mark();
-gstring * yield = string_get(Ustrlen(string) + 64);
+gstring * yield = NULL;
int item_type;
-const uschar * s = string;
+const uschar * orig_string = s;
const uschar * save_expand_nstring[EXPAND_MAXN+1];
int save_expand_nlength[EXPAND_MAXN+1];
BOOL resetok = TRUE, first = TRUE, textonly = TRUE;
@@ -4636,7 +4637,7 @@ expand_level++;
f.expand_string_forcedfail = FALSE;
expand_string_message = US"";
-if (is_tainted(string))
+if (is_tainted(s))
{
expand_string_message =
string_sprintf("attempt to expand tainted string '%s'", s);
@@ -4644,10 +4645,17 @@ if (is_tainted(string))
goto EXPAND_FAILED;
}
+ {
+ int len = Ustrlen(s);
+ if (len) yield = string_get(len + 64);
+ }
+
while (*s)
{
uschar name[256];
+ if (flags & ESI_EXISTS_ONLY && gstring_length(yield) > 0) break;
+
DEBUG(D_expand)
{
debug_printf_indent("%V%V%s: %W\n",
@@ -8491,7 +8499,7 @@ left != NULL, return a pointer to the terminator. */
BOOL tainted = is_tainted(res);
debug_printf_indent("%Vexpanded: %.*W\n",
"K---",
- (int)(s - string), string);
+ (int)(s - orig_string), orig_string);
debug_printf_indent("%Vresult: ",
flags & ESI_SKIPPING ? "K-----" : "\\_____");
if (*res || !(flags & ESI_SKIPPING))
@@ -8533,7 +8541,7 @@ EXPAND_FAILED:
if (left) *left = s;
DEBUG(D_expand)
{
- debug_printf_indent("%Vfailed to expand: %s\n", "K", string);
+ debug_printf_indent("%Vfailed to expand: %s\n", "K", orig_string);
debug_printf_indent("%Verror message: %s\n",
f.expand_string_forcedfail ? "K---" : "\\___", expand_string_message);
if (f.expand_string_forcedfail)
@@ -8584,6 +8592,17 @@ expand_string(uschar * string)
{ return US expand_string_2(CUS string, NULL); }
+/* Just return whether the string is non-empty after expansion */
+
+BOOL
+expand_string_nonempty(const uschar * string)
+{
+const uschar * s;
+if (!string) return FALSE;
+s = expand_string_internal(string, ESI_HONOR_DOLLAR | ESI_EXISTS_ONLY,
+ NULL, NULL, NULL);
+return s && *s;
+}
diff --git a/src/src/functions.h b/src/src/functions.h
index ee6b1ff2d..21c3eecb6 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -235,6 +235,7 @@ extern uschar *expand_file_big_buffer(const uschar *);
extern uschar *expand_string(uschar *); /* public, cannot make const */
extern const uschar *expand_string_2(const uschar *, BOOL *);
extern const uschar *expand_cstring(const uschar *); /* ... so use this one */
+extern BOOL expand_string_nonempty(const uschar *);
extern uschar *expand_getkeyed(const uschar *, const uschar *);
extern uschar *expand_hide_passwords(uschar * );
diff --git a/src/src/verify.c b/src/src/verify.c
index b48d17ee5..cfd4eadc9 100644
--- a/src/src/verify.c
+++ b/src/src/verify.c
@@ -1115,22 +1115,24 @@ no_conn:
if (cutthrough.delivery)
{
- if (addr->transport->filter_command)
+ if (expand_string_nonempty(addr->transport->filter_command))
{
cutthrough.delivery= FALSE;
HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of transport filter\n");
}
#ifndef DISABLE_DKIM
- /* DKIM signing needs to add a header after seeing the whole body, so we cannot just copy
- body bytes to the outbound as they are received, which is the intent of cutthrough. */
- if (ob->dkim.dkim_domain)
+ /* DKIM signing needs to add a header after seeing the whole body, so we
+ cannot just copy body bytes to the outbound as they are received, which is
+ the intent of cutthrough. */
+ if (expand_string_nonempty(ob->dkim.dkim_domain))
{
cutthrough.delivery= FALSE;
HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of DKIM signing\n");
}
#endif
#ifdef EXPERIMENTAL_ARC
- if (ob->arc_sign)
+ /* ARC has the same issue as DKIM above */
+ if (expand_string_nonempty(ob->arc_sign))
{
cutthrough.delivery= FALSE;
HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of ARC signing\n");
--
## subscription configuration (requires account):
##
https://lists.exim.org/mailman3/postorius/lists/exim-cvs.lists.exim.org/
## unsubscribe (doesn't require an account):
## exim-cvs-unsubscribe@???
## Exim details at
http://www.exim.org/
## Please use the Wiki with this list -
http://wiki.exim.org/