summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/doc-docbook/spec.xfpt9
-rw-r--r--doc/doc-txt/NewStuff2
-rw-r--r--src/src/expand.c16
-rw-r--r--test/scripts/0000-Basic/00024
-rw-r--r--test/stdout/00025
5 files changed, 33 insertions, 3 deletions
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 7b5e3ccd5..3ab63e5ec 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -10158,6 +10158,15 @@ escape sequences starting with a backslash. Whether characters with the most
significant bit set (so-called &"8-bit characters"&) count as printing or not
is controlled by the &%print_topbitchars%& option.
+.new
+.vitem &*${escape8bit:*&<&'string'&>&*}*&
+.cindex "expansion" "escaping 8-bit characters"
+.cindex "&%escape8bit%& expansion item"
+If the string contains and characters with the most significant bit set,
+they are converted to escape sequences starting with a backslash.
+Backslashes and DEL characters are also converted.
+.wen
+
.vitem &*${eval:*&<&'string'&>&*}*&&~and&~&*${eval10:*&<&'string'&>&*}*&
.cindex "expansion" "expression evaluation"
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index cf1cf6d56..219c3c3fb 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -35,6 +35,8 @@ Version 4.88
8. LMDB lookup support, as Experimental. Patch supplied by Andrew Colin Kissa.
+ 9. Expansion operator escape8bit, like escape but not touching newline etc..
+
Version 4.87
------------
diff --git a/src/src/expand.c b/src/src/expand.c
index c13284d8e..fd55436a2 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -207,6 +207,7 @@ static uschar *op_table_main[] = {
US"base64d",
US"domain",
US"escape",
+ US"escape8bit",
US"eval",
US"eval10",
US"expand",
@@ -252,6 +253,7 @@ enum {
EOP_BASE64D,
EOP_DOMAIN,
EOP_ESCAPE,
+ EOP_ESCAPE8BIT,
EOP_EVAL,
EOP_EVAL10,
EOP_EXPAND,
@@ -7109,11 +7111,23 @@ while (*s != 0)
case EOP_ESCAPE:
{
- const uschar *t = string_printing(sub);
+ const uschar * t = string_printing(sub);
yield = string_cat(yield, &size, &ptr, t);
continue;
}
+ case EOP_ESCAPE8BIT:
+ {
+ const uschar * s = sub;
+ uschar c;
+
+ for (s = sub; c = *s; s++)
+ yield = c < 127 && c != '\\'
+ ? string_catn(yield, &size, &ptr, s, 1)
+ : string_catn(yield, &size, &ptr, string_sprintf("\\%03o", c), 4);
+ continue;
+ }
+
/* Handle numeric expression evaluation */
case EOP_EVAL:
diff --git a/test/scripts/0000-Basic/0002 b/test/scripts/0000-Basic/0002
index dafcba7f0..c2dcc40d9 100644
--- a/test/scripts/0000-Basic/0002
+++ b/test/scripts/0000-Basic/0002
@@ -132,7 +132,9 @@ addresses: ${addresses:Exim Person <local-part@dom.ain> (that's me), \
xyz@abc, nullgroupname:;, group: p@q, r@s; }
addresses: ${addresses:local-part@dom.ain <local-part@dom.ain>}
-escape: ${escape:B7·F2ò}
+escape: ${escape:B7·F2ò}
+excape8bit: ${escape8bit:undisturbed text\ttab\nnewline\ttab\\backslash \176tilde\177DEL\200\x81.}
+
eval: ${eval:1+1}
eval: ${eval:1+2*3}
eval: ${eval:(1+2)*3}
diff --git a/test/stdout/0002 b/test/stdout/0002
index a19cc526c..b6ca54d48 100644
--- a/test/stdout/0002
+++ b/test/stdout/0002
@@ -122,7 +122,10 @@
> addresses: local-part@dom.ain:xyz@abc:p@q:r@s
> addresses:
>
-> escape: B7\267F2\362
+> escape: B7\267F2\362
+> excape8bit: undisturbed text tab
+newline tab\134backslash ~tilde\177DEL\200\201.
+>
> eval: 2
> eval: 7
> eval: 9