From: Philippe Wooding Date: Mon, 4 Jun 2018 13:01:56 +0000 (+0000) Subject: Convert tolower xlat to new async API X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e85ec054504b8133a0f10aeefd87afee3cf80908;p=thirdparty%2Ffreeradius-server.git Convert tolower xlat to new async API --- diff --git a/src/lib/server/xlat_func.c b/src/lib/server/xlat_func.c index 33ab07a2136..89be9233e2d 100644 --- a/src/lib/server/xlat_func.c +++ b/src/lib/server/xlat_func.c @@ -1061,31 +1061,62 @@ static xlat_action_t urlunquote_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, return XLAT_ACTION_DONE; } - -/** Convert a string to lowercase +/** Change case of a string * - * Example: "%{tolower:Bar}" == "bar" + * If upper is true, change to uppercase, otherwise, change to lowercase * - * Probably only works for ASCII */ -static ssize_t tolower_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, - UNUSED void const *mod_inst, UNUSED void const *xlat_inst, - UNUSED REQUEST *request, char const *fmt) +static xlat_action_t _xlat_change_case(bool upper, TALLOC_CTX *ctx, fr_cursor_t *out, + REQUEST *request, fr_value_box_t **in) { - char *q; - char const *p; + char *buff, *buff_p; + char const *p, *end; + fr_value_box_t* vb; - if (outlen <= 1) return 0; + /* + * If there's no input, there's no output + */ + if (!*in) return XLAT_ACTION_DONE; - for (p = fmt, q = *out; *p != '\0'; p++, outlen--) { - if (outlen <= 1) break; + /* + * Concatenate all input + */ + if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { + RPEDEBUG("Failed concatenating input"); + return XLAT_ACTION_FAIL; + } + + p = (*in)->vb_strvalue; + end = p + (*in)->vb_length; - *(q++) = tolower((int) *p); + buff = buff_p = talloc_array(NULL, char, (*in)->vb_length + 1); + + while (p < end) { + *(buff_p++) = upper ? toupper ((int) *(p++)) : tolower((int) *(p++)); } - *q = '\0'; + *buff_p = '\0'; - return strlen(*out); + MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL, false)); + fr_value_box_bstrsteal(vb, vb, NULL, buff, false); + + fr_cursor_append(out, vb); + + return XLAT_ACTION_DONE; +} + + +/** Convert a string to lowercase + * + * Example: "%{tolower:Bar}" == "bar" + * + * Probably only works for ASCII + */ +static xlat_action_t tolower_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, + REQUEST *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, + fr_value_box_t **in) +{ + return _xlat_change_case(false, ctx, out, request, in); } /** Convert a string to uppercase @@ -2615,7 +2646,6 @@ int xlat_init(void) XLAT_REGISTER(module); XLAT_REGISTER(debug_attr); - xlat_register(NULL, "tolower", tolower_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true); xlat_register(NULL, "toupper", toupper_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true); xlat_register(NULL, "sha1", sha1_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true); #ifdef HAVE_OPENSSL_EVP_H @@ -2661,6 +2691,7 @@ int xlat_init(void) #endif xlat_async_register(NULL, "urlquote", urlquote_xlat, NULL, NULL, NULL, NULL, NULL, NULL, NULL); xlat_async_register(NULL, "urlunquote", urlunquote_xlat, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + xlat_async_register(NULL, "tolower", tolower_xlat, NULL, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } @@ -2674,5 +2705,3 @@ void xlat_free(void) xlat_root = NULL; talloc_free(xr); } - - diff --git a/src/tests/keywords/tolower b/src/tests/keywords/tolower new file mode 100644 index 00000000000..8eec1a0642b --- /dev/null +++ b/src/tests/keywords/tolower @@ -0,0 +1,26 @@ +# +# PRE: update if +# +update { + &Tmp-String-0 := "AbCdE" +} + +update request { + &Tmp-String-0 := "%{tolower:%{Tmp-String-0}}" + &Tmp-String-1 := "%{tolower:AAbbCCdd}" + &Tmp-String-2 := "%{tolower:%{Tmp-String-9}}" +} + +if (&Tmp-String-0 != "abcde") { + test_fail +} + +if (&Tmp-String-1 != "aabbccdd") { + test_fail +} + +if (&Tmp-String-2 != "") { + test_fail +} + +success