httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stefan Fritsch ...@sfritsch.de>
Subject Re: Fwd: svn commit: r1204087 - in /httpd/httpd/trunk: include/ap_expr.h include/ap_mmn.h server/util_expr_eval.c server/util_expr_parse.c server/util_expr_parse.y
Date Mon, 21 Nov 2011 16:33:30 GMT
On Monday 21 November 2011, Rüdiger Plüm wrote:
> -------- Original-Nachricht --------
> Betreff: 	svn commit: r1204087 - in /httpd/httpd/trunk:
> include/ap_expr.h include/ap_mmn.h server/util_expr_eval.c
> server/util_expr_parse.c server/util_expr_parse.y
> Datum: 	Sat, 19 Nov 2011 21:58:49 GMT
> Von: 	sf@apache.org
> 
> 
> 
> Author: sf
> Date: Sat Nov 19 21:58:48 2011
> New Revision: 1204087
> 
> URL: http://svn.apache.org/viewvc?rev=1204087&view=rev
> Log:
> Limit recursion in ap_expr evaluation to avoid unbounded stack
> usage * evaluate chains of ||,&&, and string concatenation
> non-recursively * limit other types of recursion to 20 levels
> * avoid some string copies if concatenating more than 2 strings
> 
> Modified:
>      httpd/httpd/trunk/include/ap_expr.h
>      httpd/httpd/trunk/include/ap_mmn.h
>      httpd/httpd/trunk/server/util_expr_eval.c
>      httpd/httpd/trunk/server/util_expr_parse.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_ev
> al.c?rev=1204087&r1=1204086&r2=1204087&view=diff
> ==================================================================
> ============ --- httpd/httpd/trunk/server/util_expr_eval.c
> (original)
> +++ httpd/httpd/trunk/server/util_expr_eval.c Sat Nov 19 21:58:48
> 2011
> 
> @@ -657,30 +702,81 @@ static int ap_expr_eval(ap_expr_eval_ctx
>   {
>       const ap_expr_t *e1 = node->node_arg1;
>       const ap_expr_t *e2 = node->node_arg2;
> -    switch (node->node_op) {
> -    case op_True:
> -        return 1;
> -    case op_False:
> -        return 0;
> -    case op_Not:
> -        return (!ap_expr_eval(ctx, e1));
> -    case op_Or:
> -        return (ap_expr_eval(ctx, e1) || ap_expr_eval(ctx, e2));
> -    case op_And:
> -        return (ap_expr_eval(ctx, e1)&&  ap_expr_eval(ctx, e2));
> -    case op_UnaryOpCall:
> -        return ap_expr_eval_unary_op(ctx, e1, e2);
> -    case op_BinaryOpCall:
> -        return ap_expr_eval_binary_op(ctx, e1, e2);
> -    case op_Comp:
> -        if (ctx->info->flags&  AP_EXPR_FLAG_SSL_EXPR_COMPAT)
> -            return ssl_expr_eval_comp(ctx, e1);
> -        else
> -            return ap_expr_eval_comp(ctx, e1);
> -    default:
> -        *ctx->err = "Internal evaluation error: Unknown expression
> node"; -        return FALSE;
> +    int result = FALSE;
> +    if (inc_rec(ctx))
> +        return result;
> +    while (1) {
> +        switch (node->node_op) {
> +        case op_True:
> +            result ^= TRUE;
> 
> Why all these XOR operations and no simple assignments?

To take into account NOT operators encountered before. These are also 
processed non-recursively.

> 
> +            goto out;
> +        case op_False:
> +            ctx->reclvl--;
> 
> Why this? We already decrement below.

Accidental left-overs. Already removed in r1204090

> +            result ^= FALSE;
> +            goto out;
> +        case op_Not:
> +            result = !result;
> +            node = e1;
> +            break;
> +        case op_Or:
> +            do {
> +                if (e1->node_op == op_Not) {
> +                    if (!ap_expr_eval(ctx, e1->node_arg1)) {
> +                        result ^= TRUE;
> +                        goto out;
> +                    }
> +                }
> +                else {
> +                    if (ap_expr_eval(ctx, e1)) {
> +                        ctx->reclvl--;
> 
> 
> Why this? We already decrement below.

Dito

> 
> +                        result ^= TRUE;
> +                        goto out;
> +                    }
> +                }
> +                node = node->node_arg2;
> +                e1 = node->node_arg1;
> +            } while (node->node_op == op_Or);
> +            break;
> +        case op_And:
> +            do {
> +                if (e1->node_op == op_Not) {
> +                    if (ap_expr_eval(ctx, e1->node_arg1)) {
> +                        result ^= FALSE;
> +                        goto out;
> +                    }
> +                }
> +                else {
> +                    if (!ap_expr_eval(ctx, e1)) {
> +                        result ^= FALSE;
> +                        goto out;
> +                    }
> +                }
> +                node = node->node_arg2;
> +                e1 = node->node_arg1;
> +            } while (node->node_op == op_And);
> +            break;
> +        case op_UnaryOpCall:
> +            result ^= ap_expr_eval_unary_op(ctx, e1, e2);
> +            goto out;
> +        case op_BinaryOpCall:
> +            result ^= ap_expr_eval_binary_op(ctx, e1, e2);
> +            goto out;
> +        case op_Comp:
> +            if (ctx->info->flags&  AP_EXPR_FLAG_SSL_EXPR_COMPAT)
> +                result ^= ssl_expr_eval_comp(ctx, e1);
> +            else
> +                result ^= ap_expr_eval_comp(ctx, e1);
> +            goto out;
> +        default:
> +            *ctx->err = "Internal evaluation error: Unknown
> expression node"; +            goto out;
> +        }
> +        e1 = node->node_arg1;
> +        e2 = node->node_arg2;
>       }
> +out:
> +    ctx->reclvl--;
> +    return result;
>   }
> 
>   AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t
> *info,


Mime
View raw message