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: [email protected]
>
>
>
> 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,