diff options
-rw-r--r-- | doc/doc-docbook/spec.xfpt | 15 | ||||
-rw-r--r-- | doc/doc-txt/NewStuff | 2 | ||||
-rw-r--r-- | src/src/expand.c | 48 | ||||
-rw-r--r-- | test/scripts/0000-Basic/0002 | 14 | ||||
-rw-r--r-- | test/stdout/0002 | 14 |
5 files changed, 93 insertions, 0 deletions
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index d3307eacd..d08a7a040 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -10090,6 +10090,21 @@ Last:user@example.com user@example.com .endd +.new +.vitem &*${base32:*&<&'digits'&>&*}*& +.cindex "&%base32%& expansion item" +.cindex "expansion" "conversion to base 32" +The string must consist entirely of decimal digits. The number is converted to +base 32 and output as a (empty, for zero) string of characters. +Only lowercase letters are used. + +.vitem &*${base32d:*&<&'base-32&~digits'&>&*}*& +.cindex "&%base32d%& expansion item" +.cindex "expansion" "conversion to base 32" +The string must consist entirely of base-32 digits. +The number is converted to decimal and output as a string. +.wen + .vitem &*${base62:*&<&'digits'&>&*}*& .cindex "&%base62%& expansion item" .cindex "expansion" "conversion to base 62" diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 2a776b730..587dc6508 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -26,6 +26,8 @@ Version 4.88 the queue to be used for a message. A $queue_name variable gives visibility. + 6. New expansion operators base32/base32d. + Version 4.87 ------------ diff --git a/src/src/expand.c b/src/src/expand.c index 2c23f13e4..10874add3 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -199,6 +199,8 @@ enum { static uschar *op_table_main[] = { US"address", US"addresses", + US"base32", + US"base32d", US"base62", US"base62d", US"base64", @@ -242,6 +244,8 @@ static uschar *op_table_main[] = { enum { EOP_ADDRESS = nelem(op_table_underscore), EOP_ADDRESSES, + EOP_BASE32, + EOP_BASE32D, EOP_BASE62, EOP_BASE62D, EOP_BASE64, @@ -838,6 +842,9 @@ static int utf8_table2[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; } + +static uschar * base32_chars = US"abcdefghijklmnopqrstuvwxyz234567"; + /************************************************* * Binary chop search on a table * *************************************************/ @@ -6257,6 +6264,47 @@ while (*s != 0) switch(c) { + case EOP_BASE32: + { + uschar *t; + unsigned long int n = Ustrtoul(sub, &t, 10); + uschar * s = NULL; + int sz = 0, i = 0; + + if (*t != 0) + { + expand_string_message = string_sprintf("argument for base32 " + "operator is \"%s\", which is not a decimal number", sub); + goto EXPAND_FAILED; + } + for ( ; n; n >>= 5) + s = string_catn(s, &sz, &i, &base32_chars[n & 0x1f], 1); + + while (i > 0) yield = string_catn(yield, &size, &ptr, &s[--i], 1); + continue; + } + + case EOP_BASE32D: + { + uschar *tt = sub; + unsigned long int n = 0; + uschar * s; + while (*tt) + { + uschar * t = Ustrchr(base32_chars, *tt++); + if (t == NULL) + { + expand_string_message = string_sprintf("argument for base32d " + "operator is \"%s\", which is not a base 32 number", sub); + goto EXPAND_FAILED; + } + n = n * 32 + (t - base32_chars); + } + s = string_sprintf("%ld", n); + yield = string_cat(yield, &size, &ptr, s); + continue; + } + case EOP_BASE62: { uschar *t; diff --git a/test/scripts/0000-Basic/0002 b/test/scripts/0000-Basic/0002 index 278a38660..dafcba7f0 100644 --- a/test/scripts/0000-Basic/0002 +++ b/test/scripts/0000-Basic/0002 @@ -179,6 +179,20 @@ hex2b64:${hex2b64:1a2b3c4d5e6g} hex2b64:${hex2b64:${md5:the quick brown fox}} hex2b64:${hex2b64:${sha1:the quick brown fox}} +base32: 0 <${base32:0}> +base32: 1 <${base32:1}> +base32: 31 <${base32:31}> +base32: 32 <${base32:32}> +base32: 42 <${base32:42}> +base32 error: 0x1 ${base32:0x1} + +base32d: 0 ${base32d:${base32:0}} +base32d: 1 ${base32d:${base32:1}} +base32d: 31 ${base32d:${base32:31}} +base32d: 32 ${base32d:${base32:32}} +base32d: 42 ${base32d:${base32:42}} +base32d error: ABC ${base32d:ABC} + The base62 operator is actually a base36 operator in the Darwin and Cygwin environments. Write cunning tests that produce the same output in both cases, while doing a reasonable check. diff --git a/test/stdout/0002 b/test/stdout/0002 index 0bbd4c754..a19cc526c 100644 --- a/test/stdout/0002 +++ b/test/stdout/0002 @@ -169,6 +169,20 @@ > hex2b64:MPPJPkZDbetYunCBao7BJA== > hex2b64:ztcfpyNSMb7Tg/rP3EHE3cwi7PE= > +> base32: 0 <> +> base32: 1 <b> +> base32: 31 <7> +> base32: 32 <ba> +> base32: 42 <bk> +> Failed: argument for base32 operator is "0x1", which is not a decimal number +> +> base32d: 0 0 +> base32d: 1 1 +> base32d: 31 31 +> base32d: 32 32 +> base32d: 42 42 +> Failed: argument for base32d operator is "ABC", which is not a base 32 number +> > The base62 operator is actually a base36 operator in the Darwin and Cygwin > environments. Write cunning tests that produce the same output in both cases, > while doing a reasonable check. |