From 3367f8c2e08bf998efc84050e39d5a9fbdffb5dd Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 14 Aug 2016 15:11:04 +0100 Subject: [PATCH] Expansions: new ${escape8bit:} operator. Bug 1863 --- doc/doc-docbook/spec.xfpt | 9 +++++++++ doc/doc-txt/NewStuff | 2 ++ src/src/expand.c | 16 +++++++++++++++- test/scripts/0000-Basic/0002 | 4 +++- test/stdout/0002 | 5 ++++- 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 (that's me), \ xyz@abc, nullgroupname:;, group: p@q, r@s; } addresses: ${addresses: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 -- 2.30.2