]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
more clearly separate pre/post expansion parsing.
authorAlan T. DeKok <aland@freeradius.org>
Tue, 21 Jun 2022 15:26:19 +0000 (11:26 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 21 Jun 2022 15:29:20 +0000 (11:29 -0400)
We first parse the condition *without* doing variable expansion.
this lets us know how big the condition is.

We then expand the variables and re-parse the condition.

This two-pass method is a temporary hack until we get the new
xlat expressions working.

src/bin/unit_test_attribute.c
src/lib/server/cf_file.c
src/lib/server/cond.h
src/lib/server/cond_tokenize.c
src/lib/unlang/compile.c

index 295d7516735115443959a4d95f791f97d86b98cf..50a4ae27edeac4c58a9a2f8197ca056aa1d8af2f 100644 (file)
@@ -1448,7 +1448,7 @@ static size_t command_condition_normalise(command_result_t *result, command_file
        cf_filename_set(cs, cc->filename);
        cf_lineno_set(cs, cc->lineno);
 
-       dec_len = fr_cond_tokenize(cs, &cond, &cc->tmpl_rules, &FR_SBUFF_IN(in, inlen));
+       dec_len = fr_cond_tokenize(cs, &cond, &cc->tmpl_rules, &FR_SBUFF_IN(in, inlen), false);
        if (dec_len <= 0) {
                fr_strerror_printf_push_head("ERROR offset %d", (int) -dec_len);
 
index e9d9ee8f157a7796ac6b9be5ee23b8772f818490..bc505c6e569f24d0d96323d1e917ac6be407e850 100644 (file)
@@ -1211,12 +1211,14 @@ static CONF_ITEM *process_if(cf_stack_t *stack)
                ssize_t end;
                char *spaces, *text;
 
+               ERROR("INPUT %s", ptr);
+
                /*
                 *      Parse the condition.  If it succeeded, stop
                 *      trying to expand the buffer.
                 */
                slen = fr_cond_tokenize(cs, &cond,
-                                       &t_rules, &FR_SBUFF_IN(ptr, strlen(ptr)));
+                                       &t_rules, &FR_SBUFF_IN(ptr, strlen(ptr)), true);
                if (slen > 0) break;
 
                end = -slen;
@@ -1271,7 +1273,7 @@ static CONF_ITEM *process_if(cf_stack_t *stack)
         *      condition, expand the variables, and reparse the
         *      condition.
         */
-       if (strchr(ptr, '$') != NULL) {
+       {
                ssize_t my_slen;
 
                talloc_free(cond);
@@ -1282,7 +1284,7 @@ static CONF_ITEM *process_if(cf_stack_t *stack)
                        return NULL;
                }
 
-               my_slen = fr_cond_tokenize(cs, &cond, &t_rules, &FR_SBUFF_IN(buff[3], strlen(buff[3])));
+               my_slen = fr_cond_tokenize(cs, &cond, &t_rules, &FR_SBUFF_IN(buff[3], strlen(buff[3])), false);
                if (my_slen <= 0) {
                        ptr = buff[3];
                        slen = my_slen;
@@ -1296,15 +1298,6 @@ static CONF_ITEM *process_if(cf_stack_t *stack)
                        slen = my_slen;
                        goto parse_error;
                }
-       } else {
-               ssize_t my_slen;
-
-               my_slen = xlat_tokenize_expression(cs, &head, &FR_SBUFF_IN(buff[2], strlen(buff[2])), &p_rules, &t_rules);
-               if (my_slen <= 0) {
-                       ptr = buff[2];
-                       slen = my_slen;
-                       goto parse_error;
-               }
 #endif
        }
 
index fb8a532bf042201e2e810829db695dd6b2d36c92..1bdbe6eb475fcaced163e82d0d13010738bac718 100644 (file)
@@ -99,9 +99,9 @@ typedef struct {
        fr_cond_t       *cond;
 } fr_cond_iter_t;
 
-ssize_t        fr_cond_tokenize(CONF_SECTION *cs, fr_cond_t **head, tmpl_rules_t const *rules, fr_sbuff_t *in) CC_HINT(nonnull(1,2,4));
+ssize_t        fr_cond_tokenize(CONF_SECTION *cs, fr_cond_t **head, tmpl_rules_t const *rules, fr_sbuff_t *in, bool flag) CC_HINT(nonnull(1,2,4));
 
-int    fr_cond_promote_types(fr_cond_t *c, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs, fr_sbuff_marker_t *m_rhs) CC_HINT(nonnull(1));
+int    fr_cond_promote_types(fr_cond_t *c, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs, fr_sbuff_marker_t *m_rhs, bool flag) CC_HINT(nonnull(1));
 
 ssize_t        cond_print(fr_sbuff_t *out, fr_cond_t const *c);
 
index 4f9b9784731af7ff9b9eeffde3571befa1af3a21..eb58c2c6866a377229bf9e9c7bb9b396a4adfcc6 100644 (file)
@@ -211,7 +211,7 @@ static int cond_cast_tmpl(tmpl_t *vpt, fr_type_t type, tmpl_t *other)
 /** Promote the types in a FOO OP BAR comparison.
  *
  */
-int fr_cond_promote_types(fr_cond_t *c, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs, fr_sbuff_marker_t *m_rhs)
+int fr_cond_promote_types(fr_cond_t *c, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs, fr_sbuff_marker_t *m_rhs, bool flag)
 {
        fr_type_t lhs_type, rhs_type;
        fr_type_t cast_type;
@@ -482,6 +482,11 @@ set_types:
                }
        }
 
+       /*
+        *      Skip casting.
+        */
+       if (flag) return 0;
+
        /*
         *      Cast both sides to the promoted type.
         */
@@ -1070,13 +1075,14 @@ static ssize_t cond_tokenize_operand(fr_cond_t *c, tmpl_t **out,
  *  @param[in] in      the start of the string to process.  Should be "(..."
  *  @param[in] brace   look for a closing brace (how many deep we are)
  *  @param[in] t_rules for attribute parsing
+ *  @param[in] flag    temporary hack
  *  @return
  *     - Length of the string skipped.
  *     - < 0 (the offset to the offending error) on error.
  */
 static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out,
                             CONF_SECTION *cs, fr_sbuff_t *in, int brace,
-                            tmpl_rules_t const *t_rules)
+                            tmpl_rules_t const *t_rules, bool flag)
 {
        fr_sbuff_t              our_in = FR_SBUFF(in);
        ssize_t                 slen;
@@ -1127,7 +1133,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out,
                /*
                 *      Children are allocated from the parent.
                 */
-               slen = cond_tokenize(c, &c->data.child, cs, &our_in, brace + 1, t_rules);
+               slen = cond_tokenize(c, &c->data.child, cs, &our_in, brace + 1, t_rules, flag);
                if (slen <= 0) {
                        fr_sbuff_advance(&our_in, slen * -1);
                        goto error;
@@ -1351,7 +1357,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out,
                 *      Promote the data types to the appropriate
                 *      values.
                 */
-               if (fr_cond_promote_types(c, &our_in, &m_lhs, &m_rhs) < 0) {
+               if (fr_cond_promote_types(c, &our_in, &m_lhs, &m_rhs, flag) < 0) {
                        goto error;
                }
        } /* parse OP RHS */
@@ -1423,7 +1429,7 @@ closing_brace:
                 *      siblings are allocated from their older
                 *      siblings.
                 */
-               slen = cond_tokenize(child, &child->next, cs, &our_in, brace, t_rules);
+               slen = cond_tokenize(child, &child->next, cs, &our_in, brace, t_rules, flag);
                if (slen <= 0) {
                        fr_sbuff_advance(&our_in, slen * -1);
                        goto error;
@@ -1439,7 +1445,7 @@ closing_brace:
         *      siblings are allocated from their older
         *      siblings.
         */
-       slen = cond_tokenize(c, &c->next, cs, &our_in, brace, t_rules);
+       slen = cond_tokenize(c, &c->next, cs, &our_in, brace, t_rules, flag);
        if (slen <= 0) {
                fr_sbuff_advance(&our_in, slen * -1);
                goto error;
@@ -1480,18 +1486,19 @@ static void cond_reparent(fr_cond_t *c, fr_cond_t *parent)
  * @param[out] head    the parsed condition structure
  * @param[in] rules    for parsing operands.
  * @param[in] in       the start of the string to process.
+ * @param[in] flag     temporary hack
  * @return
  *     - Length of the string skipped.
  *     - < 0 (the offset to the offending error) on error.
  */
-ssize_t fr_cond_tokenize(CONF_SECTION *cs, fr_cond_t **head, tmpl_rules_t const *rules, fr_sbuff_t *in)
+ssize_t fr_cond_tokenize(CONF_SECTION *cs, fr_cond_t **head, tmpl_rules_t const *rules, fr_sbuff_t *in, bool flag)
 {
        ssize_t slen;
        fr_sbuff_t our_in = FR_SBUFF(in);
 
        *head = NULL;
 
-       slen = cond_tokenize(cs, head, cs, &our_in, 0, rules);
+       slen = cond_tokenize(cs, head, cs, &our_in, 0, rules, flag);
        if (slen <= 0) return slen;
 
        /*
index f1c8f6c0baaa06f118f28e9e4bf292902834a886..76170b74a662a03bae5c0680bface047a32f4aae 100644 (file)
@@ -303,7 +303,7 @@ static bool pass2_fixup_cond_map(fr_cond_t *c, CONF_ITEM *ci, fr_dict_t const *d
                 *      Now that we have known data types for the LHS
                 *      / RHS attribute(s), go check them.
                 */
-               if (fr_cond_promote_types(c, NULL, NULL, NULL) < 0) {
+               if (fr_cond_promote_types(c, NULL, NULL, NULL, false) < 0) {
                        cf_log_perr(ci, "Failed parsing condition after dynamic attributes were defined");
                        return false;
                }