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

2021-08-03 Thread Eric Covener
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

2021-08-03 Thread Eric Covener
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

2021-08-03 Thread Eric Covener
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

2014-12-21 Thread Graham Leggett
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

2014-12-21 Thread Eric Covener
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

2014-12-05 Thread Eric Covener
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

2014-12-05 Thread Jan Kaluža

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

2014-12-05 Thread Eric Covener
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

2014-12-05 Thread Jan Kaluža

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

2014-12-05 Thread Yann Ylavic
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

2014-12-05 Thread Yann Ylavic
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

2014-12-05 Thread Ruediger Pluem


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

2014-12-05 Thread Yann Ylavic
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

2014-12-03 Thread Jan Kaluža

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

2014-12-02 Thread Ruediger Pluem


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