diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2020-08-14 13:09:53 +0100 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2020-08-14 14:10:06 +0100 |
commit | 7f83b348ccf4cd815e9758ab9ca1012e66324e9d (patch) | |
tree | ed6716fb83dfb0a7d35bcb4b059285dd2143f376 /src | |
parent | cebf4027931177cc70106a84e19705f2085a09f5 (diff) |
Fix ${readsocket } eol-replacement. Bug 2630
Diffstat (limited to 'src')
-rw-r--r-- | src/src/expand.c | 11 | ||||
-rw-r--r-- | src/src/functions.h | 2 | ||||
-rw-r--r-- | src/src/lookups/readsock.c | 6 | ||||
-rw-r--r-- | src/src/macros.h | 6 | ||||
-rw-r--r-- | src/src/readconf.c | 4 | ||||
-rw-r--r-- | src/src/string.c | 30 |
6 files changed, 37 insertions, 22 deletions
diff --git a/src/src/expand.c b/src/src/expand.c index 7b8462eef..9bb30de4f 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -4916,7 +4916,7 @@ while (*s) { expand_string_message = string_sprintf("lookup of \"%s\" gave DEFER: %s", - string_printing2(key, FALSE), search_error_message); + string_printing2(key, SP_TAB), search_error_message); goto EXPAND_FAILED; } if (expand_setup > 0) expand_nmax = expand_setup; @@ -5330,11 +5330,14 @@ while (*s) while ((item = string_nextinlist(&list, &sep, NULL, 0))) g = string_append_listele(g, ',', item); - /* possibly plus an EOL string */ + /* possibly plus an EOL string. Process with escapes, to protect + from list-processing. The only current user of eol= in search + options is the readsock expansion. */ + if (sub_arg[3] && *sub_arg[3]) g = string_append_listele(g, ',', - string_sprintf("eol=%s", sub_arg[3])); - + string_sprintf("eol=%s", + string_printing2(sub_arg[3], SP_TAB|SP_SPACE))); } /* Gat a (possibly cached) handle for the connection */ diff --git a/src/src/functions.h b/src/src/functions.h index f56ab3eac..e5cf7f140 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -532,7 +532,7 @@ extern int string_is_ip_address(const uschar *, int *); #ifdef SUPPORT_I18N extern BOOL string_is_utf8(const uschar *); #endif -extern const uschar *string_printing2(const uschar *, BOOL); +extern const uschar *string_printing2(const uschar *, int); extern uschar *string_split_message(uschar *); extern uschar *string_unprinting(uschar *); #ifdef SUPPORT_I18N diff --git a/src/src/lookups/readsock.c b/src/src/lookups/readsock.c index c2088b7a5..cfc9b4ad8 100644 --- a/src/src/lookups/readsock.c +++ b/src/src/lookups/readsock.c @@ -186,7 +186,9 @@ FILE * fp; gstring * yield; int ret = DEFER; -DEBUG(D_lookup) debug_printf_indent("readsock: file=\"%s\" key=\"%s\" len=%d opts=\"%s\"\n", filename, keystring, length, opts); +DEBUG(D_lookup) + debug_printf_indent("readsock: file=\"%s\" key=\"%s\" len=%d opts=\"%s\"\n", + filename, keystring, length, opts); /* Parse options */ @@ -200,7 +202,7 @@ if (opts) for (uschar * s; s = string_nextinlist(&opts, &sep, NULL, 0); ) lf.do_tls = TRUE; #endif else if (Ustrncmp(s, "eol=", 4) == 0) - eol = s + 4; + eol = string_unprinting(s + 4); else if (Ustrcmp(s, "cache=yes") == 0) lf.cache = TRUE; else if (Ustrcmp(s, "send=no") == 0) diff --git a/src/src/macros.h b/src/src/macros.h index 4c5279f0a..baac435ec 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -41,9 +41,11 @@ manipulate them. */ /* For almost all calls to convert things to printing characters, we want to -allow tabs. A macro just makes life a bit easier. */ +allow tabs & spaces. A macro just makes life a bit easier. */ -#define string_printing(s) string_printing2((s), TRUE) +#define string_printing(s) string_printing2((s), 0) +#define SP_TAB BIT(0) +#define SP_SPACE BIT(1) /* We need a special return code for "no recipients and failed to send an error diff --git a/src/src/readconf.c b/src/src/readconf.c index e3c9ed72d..dabe86348 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -1546,7 +1546,7 @@ if (flags & opt_fn_print) { if (flags & opt_fn_print_label) printf("%s = ", name); printf("%s\n", smtp_receive_timeout_s - ? string_printing2(smtp_receive_timeout_s, FALSE) + ? string_printing2(smtp_receive_timeout_s, SP_TAB) : readconf_printtime(smtp_receive_timeout)); } else if (*str == '$') @@ -2463,7 +2463,7 @@ switch(ol->type & opt_mask) case opt_rewrite: /* Show the text value */ s = *(USS value); if (!no_labels) printf("%s = ", name); - printf("%s\n", s ? string_printing2(s, FALSE) : US""); + printf("%s\n", s ? string_printing2(s, SP_TAB) : US""); break; case opt_int: diff --git a/src/src/string.c b/src/src/string.c index 1b08e7fb8..53ff0a834 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -281,17 +281,17 @@ return ch; /* This function is called for critical strings. It checks for any non-printing characters, and if any are found, it makes a new copy of the string with suitable escape sequences. It is most often called by the -macro string_printing(), which sets allow_tab TRUE. +macro string_printing(), which sets flags to 0. Arguments: s the input string - allow_tab TRUE to allow tab as a printing character + flags Bit 0: convert tabs. Bit 1: convert spaces. Returns: string with non-printers encoded as printing sequences */ const uschar * -string_printing2(const uschar *s, BOOL allow_tab) +string_printing2(const uschar *s, int flags) { int nonprintcount = 0; int length = 0; @@ -301,7 +301,10 @@ uschar *ss, *tt; while (*t != 0) { int c = *t++; - if (!mac_isprint(c) || (!allow_tab && c == '\t')) nonprintcount++; + if ( !mac_isprint(c) + || flags & SP_TAB && c == '\t' + || flags & SP_SPACE && c == ' ' + ) nonprintcount++; length++; } @@ -310,17 +313,19 @@ if (nonprintcount == 0) return s; /* Get a new block of store guaranteed big enough to hold the expanded string. */ -ss = store_get(length + nonprintcount * 3 + 1, is_tainted(s)); +tt = ss = store_get(length + nonprintcount * 3 + 1, is_tainted(s)); /* Copy everything, escaping non printers. */ -t = s; -tt = ss; - -while (*t != 0) +for (t = s; *t; ) { int c = *t; - if (mac_isprint(c) && (allow_tab || c != '\t')) *tt++ = *t++; else + if ( mac_isprint(c) + && (!(flags & SP_TAB) || c != '\t') + && (!(flags & SP_SPACE) || c != ' ') + ) + *tt++ = *t++; + else { *tt++ = '\\'; switch (*t) @@ -944,7 +949,10 @@ else s = ss; if (!*s || *++s != sep || sep_is_special) break; } - while (g->ptr > 0 && isspace(g->s[g->ptr-1])) g->ptr--; + /* while (g->ptr > 0 && isspace(g->s[g->ptr-1])) g->ptr--; */ + while ( g->ptr > 0 && isspace(g->s[g->ptr-1]) + && (g->ptr == 1 || g->s[g->ptr-2] != '\\') ) + g->ptr--; buffer = string_from_gstring(g); gstring_release_unused(g); } |