Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
http://svn.apache.org/viewvc?rev=1891989=rev http://svn.apache.org/viewvc?rev=1891990=rev On Tue, Aug 3, 2021 at 1:14 PM Eric Covener wrote: > > On Tue, Aug 3, 2021 at 11:43 AM Eric Covener wrote: > > > > It looks like replace() was broken somewhere after it was committed, > > but I can't tell how. > > Does it work for anyone? > > > > There seems to be some confusion about the arguments. > > > > 1. During parsing, a weird loop in ap_expr_info_make causes the final > > list argument to be parsed as the strmatch pattern, but the last > > element is the replacement string not the pattern (from). The 2nd > > argument is the pattern. > > Jan's example was: > > Require expr replace(%{REQUEST_METHOD}, "E", "O") == "GOT" > > and trace confirms that the pattern is "O" > > > > 2. During evaluation, The remaining arguments are passed in an array > > that skips over the first value, but it still expects three arguments > > in the array. > > [Tue Aug 03 15:32:40.807613 2021] [authz_core:error] [pid 33929:tid > > 123145531994112] [client 127.0.0.1:64195] AH03299: Evaluation of > > expression from > > /Users/covener/SRC/httpd-trunk/built/conf/httpd.conf:544 failed: > > replace() function needs exactly 3 arguments > > > > Unfortunately I think these same quirks are passed on to any > > list-based string function registered dynamically by a module. But > > fortunately they are trunk-only. > > > > Looks like some of the confusion comes from the type of the args, some > of my testing was with literal strings and some not. -- Eric Covener cove...@gmail.com
Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
On Tue, Aug 3, 2021 at 11:43 AM Eric Covener wrote: > > It looks like replace() was broken somewhere after it was committed, > but I can't tell how. > Does it work for anyone? > > There seems to be some confusion about the arguments. > > 1. During parsing, a weird loop in ap_expr_info_make causes the final > list argument to be parsed as the strmatch pattern, but the last > element is the replacement string not the pattern (from). The 2nd > argument is the pattern. > Jan's example was: > Require expr replace(%{REQUEST_METHOD}, "E", "O") == "GOT" > and trace confirms that the pattern is "O" > > 2. During evaluation, The remaining arguments are passed in an array > that skips over the first value, but it still expects three arguments > in the array. > [Tue Aug 03 15:32:40.807613 2021] [authz_core:error] [pid 33929:tid > 123145531994112] [client 127.0.0.1:64195] AH03299: Evaluation of > expression from > /Users/covener/SRC/httpd-trunk/built/conf/httpd.conf:544 failed: > replace() function needs exactly 3 arguments > > Unfortunately I think these same quirks are passed on to any > list-based string function registered dynamically by a module. But > fortunately they are trunk-only. > Looks like some of the confusion comes from the type of the args, some of my testing was with literal strings and some not.
Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
It looks like replace() was broken somewhere after it was committed, but I can't tell how. Does it work for anyone? There seems to be some confusion about the arguments. 1. During parsing, a weird loop in ap_expr_info_make causes the final list argument to be parsed as the strmatch pattern, but the last element is the replacement string not the pattern (from). The 2nd argument is the pattern. Jan's example was: Require expr replace(%{REQUEST_METHOD}, "E", "O") == "GOT" and trace confirms that the pattern is "O" 2. During evaluation, The remaining arguments are passed in an array that skips over the first value, but it still expects three arguments in the array. [Tue Aug 03 15:32:40.807613 2021] [authz_core:error] [pid 33929:tid 123145531994112] [client 127.0.0.1:64195] AH03299: Evaluation of expression from /Users/covener/SRC/httpd-trunk/built/conf/httpd.conf:544 failed: replace() function needs exactly 3 arguments Unfortunately I think these same quirks are passed on to any list-based string function registered dynamically by a module. But fortunately they are trunk-only. On Thu, Nov 27, 2014 at 8:47 AM wrote: > > Author: jkaluza > Date: Thu Nov 27 13:46:11 2014 > New Revision: 1642154 > > URL: http://svn.apache.org/r1642154 > Log: > * ap_exr: Add replace(string, from, to) function. > > Modified: > httpd/httpd/trunk/docs/manual/expr.xml > httpd/httpd/trunk/include/ap_expr.h > httpd/httpd/trunk/server/util_expr_eval.c > httpd/httpd/trunk/server/util_expr_parse.y > > Modified: httpd/httpd/trunk/docs/manual/expr.xml > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/expr.xml?rev=1642154=1642153=1642154=diff > == > --- httpd/httpd/trunk/docs/manual/expr.xml (original) > +++ httpd/httpd/trunk/docs/manual/expr.xml Thu Nov 27 13:46:11 2014 > @@ -136,7 +136,7 @@ variable::= "%{" va > > rebackref ::= "$" [0-9] > > -function ::= funcname "(" word ")" > +function ::= funcname "(" wordlist ")" > > listfunction ::= listfuncname "(" word ")" > > @@ -526,6 +526,9 @@ listfunction ::= listfuncname "( > ldap > Escape characters as required by LDAP distinguished name escaping > (RFC4514) and LDAP filter escaping (RFC4515). > +replace > +replace(string, "from", "to") replaces all occurences of "from" > +in the string with "to". > > > > > Modified: httpd/httpd/trunk/include/ap_expr.h > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_expr.h?rev=1642154=1642153=1642154=diff > == > --- httpd/httpd/trunk/include/ap_expr.h (original) > +++ httpd/httpd/trunk/include/ap_expr.h Thu Nov 27 13:46:11 2014 > @@ -232,6 +232,16 @@ typedef const char *(ap_expr_string_func > const void *data, > const char *arg); > > +/** String valued function, takes a list argument and returns a string > + * @param ctx The evaluation context > + * @param data An opaque context provided by the lookup hook function > + * @param args The list of string arguments > + * @return The functions result string, may be NULL for 'empty string' > + */ > +typedef const char *(ap_expr_string_list_func_t)(ap_expr_eval_ctx_t *ctx, > +const void *data, > +const apr_array_header_t *args); > + > /** List valued function, takes a string argument and returns a list of > strings > * Can currently only be called following the builtin '-in' operator. > * @param ctx The evaluation context > @@ -276,7 +286,9 @@ typedef struct { > const char **err; > > /** arg for pre-parsing (only if a simple string). > - * For binary ops, this is the right argument. */ > + * For binary ops, this is the right argument. > + * For functions with more arguments, this is the first string > + * argument. */ > const char *arg; > } ap_expr_lookup_parms; > > > Modified: httpd/httpd/trunk/server/util_expr_eval.c > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/server/util_expr_eval.c?rev=1642154=1642153=1642154=diff > == > --- httpd/httpd/trunk/server/util_expr_eval.c (original) > +++ httpd/httpd/trunk/server/util_expr_eval.c Thu Nov 27 13:46:11 2014 > @@ -24,6 +24,7 @@ > #include "http_protocol.h" > #include "http_request.h" > #include "ap_provider.h" > +#include "util_varbuf.h" > #include "util_expr_private.h" > #include "util_md5.h" > > @@ -32,6 +33,8 @@ > #include "apr_base64.h" > #include "apr_sha1.h" > #include "apr_version.h" > +#include "apr_strings.h" > +#include "apr_strmatch.h" > #if APR_VERSION_AT_LEAST(1,5,0) > #include "apr_escape.h" > #endif > @@ -183,13 +186,29 @@ static const char
Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
On 27 Nov 2014, at 3:46 PM, jkal...@apache.org wrote: Author: jkaluza Date: Thu Nov 27 13:46:11 2014 New Revision: 1642154 URL: http://svn.apache.org/r1642154 Log: * ap_exr: Add replace(string, from, to) function. Modified: httpd/httpd/trunk/docs/manual/expr.xml httpd/httpd/trunk/include/ap_expr.h httpd/httpd/trunk/server/util_expr_eval.c httpd/httpd/trunk/server/util_expr_parse.y Modified: httpd/httpd/trunk/docs/manual/expr.xml URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/expr.xml?rev=1642154r1=1642153r2=1642154view=diff == --- httpd/httpd/trunk/docs/manual/expr.xml (original) +++ httpd/httpd/trunk/docs/manual/expr.xml Thu Nov 27 13:46:11 2014 @@ -136,7 +136,7 @@ variable::= strong%{/strong va rebackref ::= strong$/strong [0-9] -function ::= funcname strong(/strong word strong)/strong +function ::= funcname strong(/strong wordlist strong)/strong listfunction ::= listfuncname strong(/strong word strong)/strong /pre @@ -526,6 +526,9 @@ listfunction ::= listfuncname strong( trtdcodeldap/code/td tdEscape characters as required by LDAP distinguished name escaping (RFC4514) and LDAP filter escaping (RFC4515)./tdtd/td/tr +trtdcodereplace/code/td +tdreplace(string, from, to) replaces all occurences of from +in the string with to./tdtd/td/tr /table Modified: httpd/httpd/trunk/include/ap_expr.h URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_expr.h?rev=1642154r1=1642153r2=1642154view=diff == --- httpd/httpd/trunk/include/ap_expr.h (original) +++ httpd/httpd/trunk/include/ap_expr.h Thu Nov 27 13:46:11 2014 @@ -232,6 +232,16 @@ typedef const char *(ap_expr_string_func const void *data, const char *arg); +/** String valued function, takes a list argument and returns a string + * @param ctx The evaluation context + * @param data An opaque context provided by the lookup hook function + * @param args The list of string arguments + * @return The functions result string, may be NULL for 'empty string' + */ +typedef const char *(ap_expr_string_list_func_t)(ap_expr_eval_ctx_t *ctx, +const void *data, +const apr_array_header_t *args); + /** List valued function, takes a string argument and returns a list of strings * Can currently only be called following the builtin '-in' operator. * @param ctx The evaluation context @@ -276,7 +286,9 @@ typedef struct { const char **err; /** arg for pre-parsing (only if a simple string). - * For binary ops, this is the right argument. */ + * For binary ops, this is the right argument. + * For functions with more arguments, this is the first string + * argument. */ const char *arg; } ap_expr_lookup_parms; Modified: httpd/httpd/trunk/server/util_expr_eval.c URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/util_expr_eval.c?rev=1642154r1=1642153r2=1642154view=diff == --- httpd/httpd/trunk/server/util_expr_eval.c (original) +++ httpd/httpd/trunk/server/util_expr_eval.c Thu Nov 27 13:46:11 2014 @@ -24,6 +24,7 @@ #include http_protocol.h #include http_request.h #include ap_provider.h +#include util_varbuf.h #include util_expr_private.h #include util_md5.h @@ -32,6 +33,8 @@ #include apr_base64.h #include apr_sha1.h #include apr_version.h +#include apr_strings.h +#include apr_strmatch.h #if APR_VERSION_AT_LEAST(1,5,0) #include apr_escape.h #endif @@ -183,13 +186,29 @@ static const char *ap_expr_eval_string_f const ap_expr_t *info, const ap_expr_t *arg) { -ap_expr_string_func_t *func = (ap_expr_string_func_t *)info-node_arg1; const void *data = info-node_arg2; AP_DEBUG_ASSERT(info-node_op == op_StringFuncInfo); -AP_DEBUG_ASSERT(func != NULL); +AP_DEBUG_ASSERT(info-node_arg1 != NULL); AP_DEBUG_ASSERT(data != NULL); -return (*func)(ctx, data, ap_expr_eval_word(ctx, arg)); +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 = apr_array_make(ctx-p, 1, sizeof(char *)); +do { +const ap_expr_t *val = arg-node_arg1; +const char **new = apr_array_push(args); +*new = ap_expr_eval_word(ctx, val); + +arg = arg-node_arg2; +} while (arg != NULL); + +
Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
On Sun, Dec 21, 2014 at 6:37 AM, Graham Leggett minf...@sharp.fm wrote: I am currently getting the error “sss” (not sure what that means?) when attempting to use named regex variables in LocationMatch - can you confirm this works as expected? When I saw this I was sure it was my own mis-committted debug, but it looks like it really did come from here (r1642154). I removed t anyway.
Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
On Thu, Nov 27, 2014 at 8:46 AM, jkal...@apache.org wrote: * ap_exr: Add replace(string, from, to) function. Is it possible to evaluate this from ap_expr_str_exec()? I am stuck on trying to get it to work. I think we cannot get to multi-valued functions from the %{func:arg} syntax used when starting at string.
Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
On 12/05/2014 02:26 PM, Eric Covener wrote: On Thu, Nov 27, 2014 at 8:46 AM, jkal...@apache.org wrote: * ap_exr: Add replace(string, from, to) function. Is it possible to evaluate this from ap_expr_str_exec()? Hm, it worked for me like this: Require expr replace(%{REQUEST_METHOD}, E, O) == GOT This internally uses ap_expr_str_exec(). I am stuck on trying to get it to work. I think we cannot get to multi-valued functions from the %{func:arg} syntax used when starting at string. I think I'm lost here. Checking for ap_expr documentation, I don't see this syntax. Can you describe this more. I'm sorry, but was checking ap_expr for first time while doing this patch, so there might be things I overlooked. Regards, Jan Kaluza
Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
On Fri, Dec 5, 2014 at 11:01 AM, Jan Kaluža jkal...@redhat.com wrote: On 12/05/2014 02:26 PM, Eric Covener wrote: On Thu, Nov 27, 2014 at 8:46 AM, jkal...@apache.org wrote: * ap_exr: Add replace(string, from, to) function. Is it possible to evaluate this from ap_expr_str_exec()? Hm, it worked for me like this: Require expr replace(%{REQUEST_METHOD}, E, O) == GOT I think this uses ap_expr_exec / aka boolean result: static authz_status expr_check_authorization(request_rec *r, const char *require_line, const void *parsed_require_line) { const char *err = NULL; const struct require_expr_info *info = parsed_require_line; int rc = ap_expr_exec(r, info-expr, err); if (rc 0) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02320) Error evaluating expression in 'Require expr': %s, err); return AUTHZ_GENERAL_ERROR; } else if (rc == 0) { if (info-want_user) return AUTHZ_DENIED_NO_USER; else return AUTHZ_DENIED; } else { return AUTHZ_GRANTED; } } This internally uses ap_expr_str_exec(). I am stuck on trying to get it to work. I think we cannot get to multi-valued functions from the %{func:arg} syntax used when starting at string. I think I'm lost here. Checking for ap_expr documentation, I don't see this syntax. Can you describe this more. I'm sorry, but was checking ap_expr for first time while doing this patch, so there might be things I overlooked. I think it is the first function of its kind so it may not be easy. When you actually want a string as the net result of an expression, you start at string in ap_expr doc. string ::= stringpart | string stringpart stringpart ::= cstring | variable | rebackref variable::= %{ varname } | %{ funcname : funcargs } Full disclosure -- I don't understand this stuff so well, but I have been learning on the job trying to make a dent in documenting some different flavors of expressions in at least if and header set Foo expr= so there is a starting point.
Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
On 12/05/2014 05:09 PM, Eric Covener wrote: On Fri, Dec 5, 2014 at 11:01 AM, Jan Kaluža jkal...@redhat.com wrote: On 12/05/2014 02:26 PM, Eric Covener wrote: On Thu, Nov 27, 2014 at 8:46 AM, jkal...@apache.org wrote: * ap_exr: Add replace(string, from, to) function. Is it possible to evaluate this from ap_expr_str_exec()? Hm, it worked for me like this: Require expr replace(%{REQUEST_METHOD}, E, O) == GOT I think this uses ap_expr_exec / aka boolean result: static authz_status expr_check_authorization(request_rec *r, const char *require_line, const void *parsed_require_line) { const char *err = NULL; const struct require_expr_info *info = parsed_require_line; int rc = ap_expr_exec(r, info-expr, err); if (rc 0) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02320) Error evaluating expression in 'Require expr': %s, err); return AUTHZ_GENERAL_ERROR; } else if (rc == 0) { if (info-want_user) return AUTHZ_DENIED_NO_USER; else return AUTHZ_DENIED; } else { return AUTHZ_GRANTED; } } This internally uses ap_expr_str_exec(). I am stuck on trying to get it to work. I think we cannot get to multi-valued functions from the %{func:arg} syntax used when starting at string. I think I'm lost here. Checking for ap_expr documentation, I don't see this syntax. Can you describe this more. I'm sorry, but was checking ap_expr for first time while doing this patch, so there might be things I overlooked. I think it is the first function of its kind so it may not be easy. When you actually want a string as the net result of an expression, you start at string in ap_expr doc. string ::= stringpart | string stringpart stringpart ::= cstring | variable | rebackref variable::= %{ varname } | %{ funcname : funcargs } Full disclosure -- I don't understand this stuff so well, but I have been learning on the job trying to make a dent in documenting some different flavors of expressions in at least if and header set Foo expr= so there is a starting point. I see what you mean now, thanks. I will need some time to actually think about possible solutions. Right now, I'm curious why we can't add: stringpart ::= function But there may be some problem with that I don't see right now. Well, I will try to play with it and let you know. Jan Kaluza
Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
On Thu, Nov 27, 2014 at 2:46 PM, jkal...@apache.org wrote: Author: jkaluza Date: Thu Nov 27 13:46:11 2014 New Revision: 1642154 URL: http://svn.apache.org/r1642154 Log: * ap_exr: Add replace(string, from, to) function. Maybe it is worth noting (doc?) that from is a ap_strmatch() pattern (with wildcards [*?]), hence eg. replace(abc*def, c*, gh) is abgh, and not abghef as one may expect. Maybe then we should name this one replace_match(), and have replace() (or replace_string) working on pure string patterns. Likewise replace_regex(string, capture, substitution) would be nice to have. Regards, Yann.
Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
On Fri, Dec 5, 2014 at 5:51 PM, Yann Ylavic ylavic@gmail.com wrote: replace(abc*def, c*, gh) is abgh, and not abghef as one may expect. s/abghef/abghdef/ above.
Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
On 12/05/2014 05:51 PM, Yann Ylavic wrote: On Thu, Nov 27, 2014 at 2:46 PM, jkal...@apache.org wrote: Author: jkaluza Date: Thu Nov 27 13:46:11 2014 New Revision: 1642154 URL: http://svn.apache.org/r1642154 Log: * ap_exr: Add replace(string, from, to) function. Maybe it is worth noting (doc?) that from is a ap_strmatch() pattern (with wildcards [*?]), hence eg. Are you sure you aren't assuming apr_fnmatch instead of apr_strmatch? Regards Rüdiger
Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
On Fri, Dec 5, 2014 at 9:05 PM, Ruediger Pluem rpl...@apache.org wrote: On 12/05/2014 05:51 PM, Yann Ylavic wrote: Maybe it is worth noting (doc?) that from is a ap_strmatch() pattern (with wildcards [*?]), hence eg. Are you sure you aren't assuming apr_fnmatch instead of apr_strmatch? Doh! Absolutely. I did not know apr_strmatch() actually, and read it as ap_strcmp_match()... Nice function though, will use it more often :p Just grep'ing strmatch now, I find this : # server/util_expr_eval.c static int op_strmatch(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg1, const char *arg2) { return (APR_SUCCESS == apr_fnmatch(arg2, arg1, 0)); } Quite confusing :) Sorry for the noise, regards, Yann.
Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
Thanks for reviewing that commit. I've fixed both issues in r1643094. Regards, Jan Kaluza On 12/02/2014 09:55 PM, Ruediger Pluem wrote: On 11/27/2014 02:46 PM, jkal...@apache.org wrote: Author: jkaluza Date: Thu Nov 27 13:46:11 2014 New Revision: 1642154 URL: http://svn.apache.org/r1642154 Log: * ap_exr: Add replace(string, from, to) function. Modified: httpd/httpd/trunk/docs/manual/expr.xml httpd/httpd/trunk/include/ap_expr.h httpd/httpd/trunk/server/util_expr_eval.c httpd/httpd/trunk/server/util_expr_parse.y Modified: httpd/httpd/trunk/server/util_expr_eval.c URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/util_expr_eval.c?rev=1642154r1=1642153r2=1642154view=diff == --- httpd/httpd/trunk/server/util_expr_eval.c (original) +++ httpd/httpd/trunk/server/util_expr_eval.c Thu Nov 27 13:46:11 2014 @@ -183,13 +186,29 @@ static const char *ap_expr_eval_string_f const ap_expr_t *info, const ap_expr_t *arg) { -ap_expr_string_func_t *func = (ap_expr_string_func_t *)info-node_arg1; const void *data = info-node_arg2; AP_DEBUG_ASSERT(info-node_op == op_StringFuncInfo); -AP_DEBUG_ASSERT(func != NULL); +AP_DEBUG_ASSERT(info-node_arg1 != NULL); AP_DEBUG_ASSERT(data != NULL); -return (*func)(ctx, data, ap_expr_eval_word(ctx, arg)); +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 = apr_array_make(ctx-p, 1, sizeof(char *)); Shouldn't we use at least 2 instead of 1? I guess we expect at least 2 elements. +do { +const ap_expr_t *val = arg-node_arg1; +const char **new = apr_array_push(args); +*new = ap_expr_eval_word(ctx, val); + +arg = arg-node_arg2; +} while (arg != NULL); + +return (*func)(ctx, data, args); +} +else { +ap_expr_string_func_t *func = (ap_expr_string_func_t *)info-node_arg1; +return (*func)(ctx, data, ap_expr_eval_word(ctx, arg)); +} } static int intstrcmp(const char *s1, const char *s2) @@ -1071,6 +1110,59 @@ static const char *ldap_func(ap_expr_eva } #endif +static int replace_func_parse_arg(ap_expr_lookup_parms *parms) +{ +const char *original = parms-arg; +const apr_strmatch_pattern *pattern; + +if (!parms-arg) { +*parms-err = apr_psprintf(parms-ptemp, replace() function needs + exactly 3 arguments); +return !OK; +} +pattern = apr_strmatch_precompile(parms-pool, original, 0); +*parms-data = pattern; +return OK; +} + +static const char *replace_func(ap_expr_eval_ctx_t *ctx, const void *data, + const apr_array_header_t *args) +{ +char *buff, *original, *replacement; +struct ap_varbuf vb; +apr_size_t repl_len; +const char *repl; +apr_size_t bytes; +apr_size_t len; +const apr_strmatch_pattern *pattern = data; +if (args-nelts != 3) { +*ctx-err = apr_psprintf(ctx-p, replace() function needs + exactly 3 arguments); +return ; +} + +buff = APR_ARRAY_IDX(args, 2, char *); +original = APR_ARRAY_IDX(args, 1, char *); +replacement = APR_ARRAY_IDX(args, 0, char *); +repl_len = strlen(replacement); +bytes = strlen(buff); + +ap_varbuf_init(ctx-p, vb, 0); +vb.strlen = 0; + +while ((repl = apr_strmatch(pattern, buff, bytes))) { +len = (apr_size_t) (repl - buff); +ap_varbuf_strmemcat(vb, buff, len); +ap_varbuf_strmemcat(vb, replacement, repl_len); + +len += repl_len; This goes wrong if replacement string and original string are of different size. IMHO you need to add strlen(original) to len above. +bytes -= len; +buff += len; +} + +return ap_varbuf_pdup(ctx-p, vb, NULL, 0, buff, bytes, len); +} + #define MAX_FILE_SIZE 10*1024*1024 static const char *file_func(ap_expr_eval_ctx_t *ctx, const void *data, char *arg) @@ -1657,6 +1749,7 @@ static const struct expr_provider_single Regards Rüdiger
Re: svn commit: r1642154 - in /httpd/httpd/trunk: docs/manual/expr.xml include/ap_expr.h server/util_expr_eval.c server/util_expr_parse.y
On 11/27/2014 02:46 PM, jkal...@apache.org wrote: Author: jkaluza Date: Thu Nov 27 13:46:11 2014 New Revision: 1642154 URL: http://svn.apache.org/r1642154 Log: * ap_exr: Add replace(string, from, to) function. Modified: httpd/httpd/trunk/docs/manual/expr.xml httpd/httpd/trunk/include/ap_expr.h httpd/httpd/trunk/server/util_expr_eval.c httpd/httpd/trunk/server/util_expr_parse.y Modified: httpd/httpd/trunk/server/util_expr_eval.c URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/util_expr_eval.c?rev=1642154r1=1642153r2=1642154view=diff == --- httpd/httpd/trunk/server/util_expr_eval.c (original) +++ httpd/httpd/trunk/server/util_expr_eval.c Thu Nov 27 13:46:11 2014 @@ -183,13 +186,29 @@ static const char *ap_expr_eval_string_f const ap_expr_t *info, const ap_expr_t *arg) { -ap_expr_string_func_t *func = (ap_expr_string_func_t *)info-node_arg1; const void *data = info-node_arg2; AP_DEBUG_ASSERT(info-node_op == op_StringFuncInfo); -AP_DEBUG_ASSERT(func != NULL); +AP_DEBUG_ASSERT(info-node_arg1 != NULL); AP_DEBUG_ASSERT(data != NULL); -return (*func)(ctx, data, ap_expr_eval_word(ctx, arg)); +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 = apr_array_make(ctx-p, 1, sizeof(char *)); Shouldn't we use at least 2 instead of 1? I guess we expect at least 2 elements. +do { +const ap_expr_t *val = arg-node_arg1; +const char **new = apr_array_push(args); +*new = ap_expr_eval_word(ctx, val); + +arg = arg-node_arg2; +} while (arg != NULL); + +return (*func)(ctx, data, args); +} +else { +ap_expr_string_func_t *func = (ap_expr_string_func_t *)info-node_arg1; +return (*func)(ctx, data, ap_expr_eval_word(ctx, arg)); +} } static int intstrcmp(const char *s1, const char *s2) @@ -1071,6 +1110,59 @@ static const char *ldap_func(ap_expr_eva } #endif +static int replace_func_parse_arg(ap_expr_lookup_parms *parms) +{ +const char *original = parms-arg; +const apr_strmatch_pattern *pattern; + +if (!parms-arg) { +*parms-err = apr_psprintf(parms-ptemp, replace() function needs + exactly 3 arguments); +return !OK; +} +pattern = apr_strmatch_precompile(parms-pool, original, 0); +*parms-data = pattern; +return OK; +} + +static const char *replace_func(ap_expr_eval_ctx_t *ctx, const void *data, + const apr_array_header_t *args) +{ +char *buff, *original, *replacement; +struct ap_varbuf vb; +apr_size_t repl_len; +const char *repl; +apr_size_t bytes; +apr_size_t len; +const apr_strmatch_pattern *pattern = data; +if (args-nelts != 3) { +*ctx-err = apr_psprintf(ctx-p, replace() function needs + exactly 3 arguments); +return ; +} + +buff = APR_ARRAY_IDX(args, 2, char *); +original = APR_ARRAY_IDX(args, 1, char *); +replacement = APR_ARRAY_IDX(args, 0, char *); +repl_len = strlen(replacement); +bytes = strlen(buff); + +ap_varbuf_init(ctx-p, vb, 0); +vb.strlen = 0; + +while ((repl = apr_strmatch(pattern, buff, bytes))) { +len = (apr_size_t) (repl - buff); +ap_varbuf_strmemcat(vb, buff, len); +ap_varbuf_strmemcat(vb, replacement, repl_len); + +len += repl_len; This goes wrong if replacement string and original string are of different size. IMHO you need to add strlen(original) to len above. +bytes -= len; +buff += len; +} + +return ap_varbuf_pdup(ctx-p, vb, NULL, 0, buff, bytes, len); +} + #define MAX_FILE_SIZE 10*1024*1024 static const char *file_func(ap_expr_eval_ctx_t *ctx, const void *data, char *arg) @@ -1657,6 +1749,7 @@ static const struct expr_provider_single Regards Rüdiger