You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Ruediger Pluem <rp...@apache.org> on 2014/12/02 21:55:11 UTC
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, jkaluza@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=1642154&r1=1642153&r2=1642154&view=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
Posted by Jan Kaluža <jk...@redhat.com>.
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, jkaluza@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=1642154&r1=1642153&r2=1642154&view=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
>