From fd4f9c92ea39447557f1847c6bdb4e178e972fec Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Mon, 15 Feb 2016 15:42:21 +0000 Subject: [PATCH] Expansions: add operators base32, base32d --- doc/doc-docbook/spec.xfpt | 15 +++++++++++ doc/doc-txt/NewStuff | 2 ++ src/src/expand.c | 48 ++++++++++++++++++++++++++++++++++++ test/scripts/0000-Basic/0002 | 14 +++++++++++ test/stdout/0002 | 14 +++++++++++ 5 files changed, 93 insertions(+) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 8a0c96753..4cc7b6ee9 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -10016,6 +10016,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 2e7648a75..65dd4b593 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -11,6 +11,8 @@ Version 4.next 1. New perl_taintmode main config option. + 2. New expansion operators base32/base32d. + Version 4.87 ------------ diff --git a/src/src/expand.c b/src/src/expand.c index 47ed70747..624c3c4db 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", @@ -241,6 +243,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, @@ -841,6 +845,9 @@ static int utf8_table2[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; } + +static uschar * base32_chars = US"abcdefghijklmnopqrstuvwxyz234567"; + /************************************************* * Binary chop search on a table * *************************************************/ @@ -6079,6 +6086,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_cat(s, &sz, &i, &base32_chars[n & 0x1f], 1); + + while (i > 0) yield = string_cat(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, Ustrlen(s)); + continue; + } + case EOP_BASE62: { uschar *t; diff --git a/test/scripts/0000-Basic/0002 b/test/scripts/0000-Basic/0002 index 105134da3..35e6f6bf9 100644 --- a/test/scripts/0000-Basic/0002 +++ b/test/scripts/0000-Basic/0002 @@ -178,6 +178,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 ee351a278..ab59183a2 100644 --- a/test/stdout/0002 +++ b/test/stdout/0002 @@ -168,6 +168,20 @@ > hex2b64:MPPJPkZDbetYunCBao7BJA== > hex2b64:ztcfpyNSMb7Tg/rP3EHE3cwi7PE= > +> base32: 0 <> +> base32: 1 +> base32: 31 <7> +> base32: 32 +> base32: 42 +> 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. -- 2.25.1