]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
make cond_eval() iterative
authorAlan T. DeKok <aland@freeradius.org>
Tue, 5 Jan 2021 16:33:09 +0000 (11:33 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 5 Jan 2021 16:34:11 +0000 (11:34 -0500)
and set c->parent correctly in cond_normalise()

src/lib/server/cond_eval.c
src/lib/server/cond_eval.h
src/lib/server/cond_tokenize.c
src/lib/unlang/condition.c

index 813189b363125d96731f4ed48dfa079dcce2c490..47fb086eea9e661096e484b986f0973342061337 100644 (file)
@@ -724,7 +724,6 @@ int cond_eval_map(request_t *request, UNUSED int depth, fr_cond_t const *c)
  *
  * @param[in] request the request_t
  * @param[in] modreturn the previous module return code
- * @param[in] depth of the recursion (only used for debugging)
  * @param[in] c the condition to evaluate
  * @return
  *     - -1 on failure.
@@ -732,9 +731,11 @@ int cond_eval_map(request_t *request, UNUSED int depth, fr_cond_t const *c)
  *     - 0 for "no match".
  *     - 1 for "match".
  */
-int cond_eval(request_t *request, rlm_rcode_t modreturn, int depth, fr_cond_t const *c)
+int cond_eval(request_t *request, rlm_rcode_t modreturn, fr_cond_t const *c)
 {
        int rcode = -1;
+       int depth = 0;
+
 #ifdef WITH_EVAL_DEBUG
        char buffer[1024];
 
@@ -757,8 +758,9 @@ int cond_eval(request_t *request, rlm_rcode_t modreturn, int depth, fr_cond_t co
                        break;
 
                case COND_TYPE_CHILD:
-                       rcode = cond_eval(request, modreturn, depth + 1, c->data.child);
-                       break;
+                       depth++;
+                       c = c->data.child;
+                       continue;
 
                case COND_TYPE_TRUE:
                        rcode = true;
@@ -772,6 +774,9 @@ int cond_eval(request_t *request, rlm_rcode_t modreturn, int depth, fr_cond_t co
                        return -1;
                }
 
+               /*
+                *      Errors cause failures.
+                */
                if (rcode < 0) return rcode;
 
                if (c->negate) rcode = !rcode;
@@ -784,13 +789,13 @@ int cond_eval(request_t *request, rlm_rcode_t modreturn, int depth, fr_cond_t co
                if (c->next) {
                        switch (c->next->type) {
                        case COND_TYPE_AND:
-                               if (!rcode) return false;
+                               if (!rcode) goto return_to_parent;
 
                                c = c->next; /* skip the && */
                                break;
 
                        case COND_TYPE_OR:
-                               if (rcode) return true;
+                               if (rcode) goto return_to_parent;
 
                                c = c->next; /* skip the || */
                                break;
@@ -800,6 +805,19 @@ int cond_eval(request_t *request, rlm_rcode_t modreturn, int depth, fr_cond_t co
                        }
                }
 
+               /*
+                *      We've fallen off of the end of this evaluation
+                *      string.  Go back up to the parent, and then to
+                *      the next sibling of the parent.
+                */
+               if (!c->next) {
+return_to_parent:
+                       c = c->parent;
+                       depth--;
+
+                       if (!c) break; /* we have to do this, otherwise the next line will fail */
+               }
+
                c = c->next;
        }
 
index 1f6b0bba461a957e289bbd379a8e629d807b0e80..93b27c2d3b122c7301f5afa53db06a60ff3829b7 100644 (file)
@@ -40,7 +40,7 @@ void  cond_debug(fr_cond_t const *cond);
 
 int    cond_eval_tmpl(request_t *request, int depth, tmpl_t const *vpt);
 int    cond_eval_map(request_t *request, int depth, fr_cond_t const *c);
-int    cond_eval(request_t *request, rlm_rcode_t modreturn, int depth, fr_cond_t const *c);
+int    cond_eval(request_t *request, rlm_rcode_t modreturn, fr_cond_t const *c);
 
 #ifdef __cplusplus
 }
index 9c79f6dcdc9fd31f7aa567f3af2f8fc1860c4b6a..2d72c9ccc98ba3cb2abbf98f99f0ed56a77c23c1 100644 (file)
@@ -653,6 +653,7 @@ static int cond_normalise(TALLOC_CTX *ctx, fr_token_t lhs_type, fr_cond_t **c_ou
                         *      !(!FOO) --> FOO, etc.
                         */
                        child->negate = (c->negate != child->negate);
+                       child->parent = c->parent;
                        talloc_free(c);
                        c = child;
                        continue;
@@ -666,6 +667,7 @@ static int cond_normalise(TALLOC_CTX *ctx, fr_token_t lhs_type, fr_cond_t **c_ou
                 */
                if (!c->next && !c->negate) {
                        (void) talloc_steal(ctx, child);
+                       child->parent = c->parent;
                        talloc_free(c);
                        c = child;
                        continue;
index 9e309834b2dc71c1e2665df08dcf19227bb9eb30..44ff151342c2bc499ae42a30d22c48d673c21207 100644 (file)
@@ -42,7 +42,7 @@ static unlang_action_t unlang_if(rlm_rcode_t *p_result, request_t *request)
        gext = unlang_group_to_cond(g);
        fr_assert(gext->cond != NULL);
 
-       condition = cond_eval(request, *p_result, 0, gext->cond);
+       condition = cond_eval(request, *p_result, gext->cond);
        if (condition < 0) {
                switch (condition) {
                case -2: