]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
hoist rcode parsing
authorAlan T. DeKok <aland@freeradius.org>
Sat, 31 Dec 2022 15:41:57 +0000 (10:41 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 13 Jan 2023 14:02:04 +0000 (09:02 -0500)
so that tmpl_tokenize functions don't need to parse bare words
as enums

src/lib/server/cond_tokenize.c
src/tests/unit/condition/base.txt
src/tests/unit/condition/regex.txt

index cbfd858e792818af18e952342990138f00b355f0..3e2b351581a26268fbae1d0e00c91aca7dc2d418 100644 (file)
@@ -1145,6 +1145,29 @@ static fr_slen_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out,
         *      Grab the LHS
         */
        fr_sbuff_marker(&m_lhs_cast, &our_in);
+
+       /*
+        *      Check to see if this is an rcode operand.  These are
+        *      common enough and specific enough to conditions that
+        *      we handle them in the condition code specifically.
+        *
+        *      Unary barewords can only be rcodes, so anything that's
+        *      not a rcode an rcode is an error.
+        */
+       {
+               rlm_rcode_t rcode;
+               size_t match_len;
+
+               fr_sbuff_out_by_longest_prefix(&match_len, &rcode, rcode_table, &our_in, RLM_MODULE_NOT_SET);
+               if (rcode != RLM_MODULE_NOT_SET) {
+                       c->type = COND_TYPE_RCODE;
+                       c->data.rcode = rcode;
+
+                       fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX, NULL);
+                       goto closing_brace;
+               }
+       }
+
        if (cond_tokenize_operand(c, &lhs, &m_lhs, &our_in, t_rules, simple_parse) < 0) goto error;
 
 #ifdef HAVE_REGEX
@@ -1208,33 +1231,6 @@ static fr_slen_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out,
                        goto error;
                }
 
-               /*
-                *      Check to see if this is an rcode operand.
-                *      These are common enough and specific enough
-                *      to conditions that we handle them in the
-                *      condition code specifically.
-                *
-                *      Unary barewords can only be rcodes, so
-                *      anything that's not a rcode an rcode
-                *      is an error.
-                */
-               if (tmpl_is_unresolved(lhs) && (lhs->quote == T_BARE_WORD)) {
-                       rlm_rcode_t rcode;
-
-                       rcode = fr_table_value_by_str(rcode_table, lhs->data.unescaped, RLM_MODULE_NOT_SET);
-                       if (rcode == RLM_MODULE_NOT_SET) {
-                               fr_strerror_const("Expected a module return code");
-                               fr_sbuff_set(&our_in, &m_lhs);
-                               goto error;
-                       }
-                       TALLOC_FREE(lhs);
-
-                       c->type = COND_TYPE_RCODE;
-                       c->data.rcode = rcode;
-
-                       goto closing_brace;
-               }
-
                c->type = COND_TYPE_TMPL;
                c->data.vpt = lhs;
 
@@ -1386,7 +1382,18 @@ closing_brace:
        fr_sbuff_out_by_longest_prefix(&slen, &cond_op, cond_logical_op_table,
                                       &our_in, COND_TYPE_INVALID);
        if (slen == 0) {
-               fr_strerror_const("Unexpected text after condition");
+               /*
+                *      Peek ahead to give slightly better error messages.
+                */
+               if (fr_sbuff_is_char(&our_in, '=')) {
+                       fr_strerror_const("Invalid location for operator");
+
+               } else if (fr_sbuff_is_char(&our_in, '!')) {
+                       fr_strerror_const("Invalid location for negation");
+
+               } else {
+                       fr_strerror_const("Expected closing brace or logical operator");
+               }
                goto error;
        }
 
index da42eb8c9bf0aea42fd77df48984054bab051894..da3fb2eb6011319288e7b86d9e4a720cc3eaf517 100644 (file)
@@ -28,29 +28,29 @@ condition (|| b)
 match ERROR offset 2: No operand found.  Expected &ref, literal, 'quoted literal', "%{expansion}", or enum value
 
 condition ((ok || handled) foo)
-match ERROR offset 18: Unexpected text after condition
+match ERROR offset 18: Expected closing brace or logical operator
 
 # escapes in names are illegal
 condition (ok\ foo || handled)
-match ERROR offset 4: Unexpected text after enum value.  Expected operator
+match ERROR offset 4: Expected closing brace or logical operator
 
 condition (Service-Type == 000-111)
 match ERROR offset 18: enum values must contain at least one alpha character
 
 condition (ok FOO handled)
-match ERROR offset 5: Invalid operator
+match ERROR offset 5: Expected closing brace or logical operator
 
 condition (ok !x handled)
-match ERROR offset 5: Invalid operator
+match ERROR offset 5: Invalid location for negation
 
 condition (ok =x handled)
-match ERROR offset 5: Invalid operator
+match ERROR offset 5: Invalid location for operator
 
 #
 # Re-enable when we have proper bareword xlat tokenization
 #
 #condition (ok == handled"foo")
-#match ERROR offset 14 Unexpected text after condition
+#match ERROR offset 14 Expected closing brace or logical operator
 
 # And now we have a bunch of VALID conditions we want to parse.
 
index 24c8bbc794a357589df4941224682cac717afd6e..af66949302636fba413469da1756345e09ea877f 100644 (file)
@@ -4,10 +4,10 @@ condition &User-Name !~ /^foo\nbar$/
 match !&User-Name =~ /^foo\nbar$/
 
 condition (ok =~ handled)
-match ERROR offset 8: Expected regular expression
+match ERROR offset 5: Invalid location for operator
 
 condition (ok == /foo/)
-match ERROR offset 8: Unexpected regular expression
+match ERROR offset 5: Invalid location for operator
 
 #
 #  bare words are cast to strings