From: Alan T. DeKok Date: Sat, 31 Dec 2022 15:41:57 +0000 (-0500) Subject: hoist rcode parsing X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7dd3787fdab07d28d11c8c5f1c46b97732335783;p=thirdparty%2Ffreeradius-server.git hoist rcode parsing so that tmpl_tokenize functions don't need to parse bare words as enums --- diff --git a/src/lib/server/cond_tokenize.c b/src/lib/server/cond_tokenize.c index cbfd858e792..3e2b351581a 100644 --- a/src/lib/server/cond_tokenize.c +++ b/src/lib/server/cond_tokenize.c @@ -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; } diff --git a/src/tests/unit/condition/base.txt b/src/tests/unit/condition/base.txt index da42eb8c9bf..da3fb2eb601 100644 --- a/src/tests/unit/condition/base.txt +++ b/src/tests/unit/condition/base.txt @@ -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. diff --git a/src/tests/unit/condition/regex.txt b/src/tests/unit/condition/regex.txt index 24c8bbc794a..af669493026 100644 --- a/src/tests/unit/condition/regex.txt +++ b/src/tests/unit/condition/regex.txt @@ -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