From: Eric Covener Date: Tue, 3 Aug 2021 18:29:35 +0000 (+0000) Subject: clarification/fixes around the replace() function X-Git-Tag: 2.5.0-alpha2-ci-test-only~876 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=700d9b5b5bc710021e978c95ef271e49bc79cc89;p=thirdparty%2Fapache%2Fhttpd.git clarification/fixes around the replace() function git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1891990 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/manual/expr.xml b/docs/manual/expr.xml index 87f56f1d779..4afb5a99bfc 100644 --- a/docs/manual/expr.xml +++ b/docs/manual/expr.xml @@ -602,7 +602,8 @@ DIGIT ::= <any US-ASCII digit "0".."9"> (RFC4514) and LDAP filter escaping (RFC4515). replace replace(string, "from", "to") replaces all occurrences of "from" - in the string with "to". + in the string with "to". The first parameter must not be a literal string. + @@ -752,9 +753,8 @@ DIGIT ::= <any US-ASCII digit "0".."9"> <If "md5('foo') == 'acbd18db4cc2f85cedef654fccc4a4d8'"> Header set checksum-matched true </If> -<If "md5('foo') == replace('md5:XXXd18db4cc2f85cedef654fccc4a4d8', 'md5:XXX', 'acb')"> - Header set checksum-matched-2 true -</If> + +Requir expr replace(%{REQUEST_METHOD}, 'E', 'O') == 'GET'" # Function example in string context Header set foo-checksum "expr=%{md5:foo}" diff --git a/include/ap_expr.h b/include/ap_expr.h index 3e1eea0be2f..8923de7db79 100644 --- a/include/ap_expr.h +++ b/include/ap_expr.h @@ -287,8 +287,9 @@ typedef struct { /** arg for pre-parsing (only if a simple string). * For binary ops, this is the right argument. - * For functions with more arguments, this is the first string - * argument. */ + * For AP_EXPR_FUNC_STRING functions with multiple arguments, this is the first + * simple/literal string argument. + */ const char *arg; } ap_expr_lookup_parms; diff --git a/server/util_expr_eval.c b/server/util_expr_eval.c index 83741345eff..823978d2f34 100644 --- a/server/util_expr_eval.c +++ b/server/util_expr_eval.c @@ -286,7 +286,7 @@ static const char *ap_expr_eval_string_func(ap_expr_eval_ctx_t *ctx, if (arg->node_op == op_ListElement) { /* Evaluate the list elements and store them in apr_array_header. */ ap_expr_string_list_func_t *func = (ap_expr_string_list_func_t *)info->node_arg1; - apr_array_header_t *args = ap_expr_list_make(ctx, arg->node_arg1); + apr_array_header_t *args = ap_expr_list_make(ctx, arg); return (*func)(ctx, data, args); } else { @@ -735,10 +735,12 @@ static ap_expr_t *ap_expr_info_make(int type, const char *name, parms.arg = arg->node_arg1; break; case op_ListElement: + /* save the first literal/simple string argument */ do { const ap_expr_t *val = arg->node_arg1; - if (val->node_op == op_String) { + if (val && val->node_op == op_String) { parms.arg = val->node_arg1; + break; } arg = arg->node_arg2; } while (arg != NULL); @@ -1424,10 +1426,10 @@ static int replace_func_parse_arg(ap_expr_lookup_parms *parms) const apr_strmatch_pattern *pattern; if (!parms->arg) { - *parms->err = apr_psprintf(parms->ptemp, "replace() function needs " - "exactly 3 arguments"); + *parms->err = apr_psprintf(parms->ptemp, "replace() function needs an argument"); return !OK; } + pattern = apr_strmatch_precompile(parms->pool, original, 0); *parms->data = pattern; return OK; @@ -1445,13 +1447,13 @@ static const char *replace_func(ap_expr_eval_ctx_t *ctx, const void *data, const apr_strmatch_pattern *pattern = data; if (args->nelts != 3) { *ctx->err = apr_psprintf(ctx->p, "replace() function needs " - "exactly 3 arguments"); + "exactly 3 arguments, got %d", args->nelts); return ""; } - buff = APR_ARRAY_IDX(args, 2, char *); + buff = APR_ARRAY_IDX(args, 0, char *); original = APR_ARRAY_IDX(args, 1, char *); - replacement = APR_ARRAY_IDX(args, 0, char *); + replacement = APR_ARRAY_IDX(args, 2, char *); repl_len = strlen(replacement); orig_len = strlen(original); bytes = strlen(buff);