From: Arran Cudbard-Bell Date: Sun, 4 Sep 2022 20:51:21 +0000 (-0400) Subject: Switch the majority of xlat functions and condition functions to returning fr_sbuff_error X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9038d878360d718546e054fb735b5acbeb984fdb;p=thirdparty%2Ffreeradius-server.git Switch the majority of xlat functions and condition functions to returning fr_sbuff_error --- diff --git a/src/bin/unit_test_attribute.c b/src/bin/unit_test_attribute.c index c578fd2f23d..a352c0f52b4 100644 --- a/src/bin/unit_test_attribute.c +++ b/src/bin/unit_test_attribute.c @@ -2547,11 +2547,16 @@ static ssize_t command_tmpl_rule_allow_unresolved(UNUSED TALLOC_CTX *ctx, tmpl_r static ssize_t command_tmpl_rule_attr_parent(UNUSED TALLOC_CTX *ctx, tmpl_rules_t *rules, fr_sbuff_t *value) { - return fr_dict_attr_by_oid_substr(NULL, + fr_dict_attr_err_t err; + fr_slen_t slen; + + slen = fr_dict_attr_by_oid_substr(&err, &rules->attr.parent, rules->attr.dict_def ? fr_dict_root(rules->attr.dict_def) : fr_dict_root(fr_dict_internal()), value, NULL); + if (err != FR_DICT_ATTR_OK) FR_SBUFF_ERROR_RETURN(value); + return slen; } static ssize_t command_tmpl_rule_disallow_internal(UNUSED TALLOC_CTX *ctx, tmpl_rules_t *rules, fr_sbuff_t *value) diff --git a/src/lib/server/cond_tokenize.c b/src/lib/server/cond_tokenize.c index 127563ff107..9858722e7de 100644 --- a/src/lib/server/cond_tokenize.c +++ b/src/lib/server/cond_tokenize.c @@ -877,7 +877,7 @@ done: return 0; } -static int cond_forbid_groups(tmpl_t *vpt, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs) +static CC_HINT(nonnull) int cond_forbid_groups(tmpl_t *vpt, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs) { if (tmpl_is_list(vpt)) { fr_strerror_const("Cannot use list references in condition"); @@ -901,9 +901,9 @@ static int cond_forbid_groups(tmpl_t *vpt, fr_sbuff_t *in, fr_sbuff_marker_t *m_ return 0; } -static ssize_t cond_tokenize_operand(fr_cond_t *c, tmpl_t **out, - fr_sbuff_marker_t *opd_start, fr_sbuff_t *in, - tmpl_rules_t const *t_rules, bool simple_parse) +static fr_slen_t cond_tokenize_operand(fr_cond_t *c, tmpl_t **out, + fr_sbuff_marker_t *opd_start, fr_sbuff_t *in, + tmpl_rules_t const *t_rules, bool simple_parse) { fr_sbuff_term_t const bareword_terminals = FR_SBUFF_TERMS( @@ -936,7 +936,7 @@ static ssize_t cond_tokenize_operand(fr_cond_t *c, tmpl_t **out, fr_type_t cast = FR_TYPE_NULL; fr_sbuff_parse_rules_t tmp_p_rules; fr_sbuff_parse_rules_t const *p_rules; - ssize_t slen; + fr_slen_t slen; tmpl_rules_t our_t_rules = *t_rules; *out = NULL; @@ -944,8 +944,7 @@ static ssize_t cond_tokenize_operand(fr_cond_t *c, tmpl_t **out, /* * Parse (optional) cast */ - slen = tmpl_cast_from_substr(&our_t_rules, &our_in); - if (slen < 0) return slen; + if (tmpl_cast_from_substr(&our_t_rules, &our_in) < 0) return fr_sbuff_error(&our_in); fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX, NULL); fr_sbuff_marker(&m, &our_in); @@ -982,18 +981,15 @@ static ssize_t cond_tokenize_operand(fr_cond_t *c, tmpl_t **out, } slen = tmpl_afrom_substr(c, &vpt, &our_in, type, p_rules, &our_t_rules); - if (!vpt) { - fr_sbuff_advance(&our_in, slen * -1); - + if (slen < 0) { error: talloc_free(vpt); - return -(fr_sbuff_used_total(&our_in)); + return fr_sbuff_error(&our_in); } if ((type != T_BARE_WORD) && !fr_sbuff_next_if_char(&our_in, fr_token_quote[type])) { /* Quoting */ fr_strerror_const("Unterminated string"); fr_sbuff_set(&our_in, &m); - fr_sbuff_advance(&our_in, 1); goto error; } @@ -1018,11 +1014,7 @@ static ssize_t cond_tokenize_operand(fr_cond_t *c, tmpl_t **out, goto error; } - slen = tmpl_regex_flags_substr(vpt, &our_in, &bareword_terminals); - if (slen < 0) { - fr_sbuff_advance(&our_in, slen * -1); - goto error; - } + if (tmpl_regex_flags_substr(vpt, &our_in, &bareword_terminals) < 0) goto error; /* * We've now got the expressions and @@ -1030,10 +1022,8 @@ static ssize_t cond_tokenize_operand(fr_cond_t *c, tmpl_t **out, * regex. */ if (!simple_parse && tmpl_is_regex_uncompiled(vpt)) { - slen = tmpl_regex_compile(vpt, true); - if (slen <= 0) { + if (tmpl_regex_compile(vpt, true) < 0) { fr_sbuff_set(&our_in, &m); /* Reset to start of expression */ - fr_sbuff_advance(&our_in, slen * -1); goto error; } } @@ -1080,9 +1070,9 @@ static ssize_t cond_tokenize_operand(fr_cond_t *c, tmpl_t **out, * - 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, bool simple_parse) +static fr_slen_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, bool simple_parse) { fr_sbuff_t our_in = FR_SBUFF(in); ssize_t slen; @@ -1101,7 +1091,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out, fr_strerror_const("Empty condition is invalid"); error: talloc_free(c); - return -(fr_sbuff_used_total(&our_in)); + FR_SBUFF_ERROR_RETURN(&our_in); } /* @@ -1133,11 +1123,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, simple_parse); - if (slen <= 0) { - fr_sbuff_advance(&our_in, slen * -1); - goto error; - } + if (cond_tokenize(c, &c->data.child, cs, &our_in, brace + 1, t_rules, simple_parse) < 0) goto error; if (!c->data.child) { fr_strerror_const("Empty condition is invalid"); @@ -1159,11 +1145,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out, * Grab the LHS */ fr_sbuff_marker(&m_lhs_cast, &our_in); - slen = cond_tokenize_operand(c, &lhs, &m_lhs, &our_in, t_rules, simple_parse); - if (!lhs) { - fr_sbuff_advance(&our_in, slen * -1); - goto error; - } + if (cond_tokenize_operand(c, &lhs, &m_lhs, &our_in, t_rules, simple_parse) < 0) goto error; #ifdef HAVE_REGEX /* @@ -1308,11 +1290,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out, * Grab the RHS */ fr_sbuff_marker(&m_rhs_cast, &our_in); - slen = cond_tokenize_operand(c, &rhs, &m_rhs, &our_in, t_rules, simple_parse); - if (!rhs) { - fr_sbuff_advance(&our_in, slen * -1); - goto error; - } + if (cond_tokenize_operand(c, &rhs, &m_rhs, &our_in, t_rules, simple_parse) < 0) goto error; /* * Groups can't be on the RHS of a comparison, either @@ -1429,12 +1407,7 @@ closing_brace: * siblings are allocated from their older * siblings. */ - slen = cond_tokenize(child, &child->next, cs, &our_in, brace, t_rules, simple_parse); - if (slen <= 0) { - fr_sbuff_advance(&our_in, slen * -1); - goto error; - } - + if (cond_tokenize(child, &child->next, cs, &our_in, brace, t_rules, simple_parse) < 0) goto error; c->next = child; goto done; } @@ -1445,16 +1418,13 @@ closing_brace: * siblings are allocated from their older * siblings. */ - slen = cond_tokenize(c, &c->next, cs, &our_in, brace, t_rules, simple_parse); - if (slen <= 0) { - fr_sbuff_advance(&our_in, slen * -1); - goto error; - } + if (cond_tokenize(c, &c->next, cs, &our_in, brace, t_rules, simple_parse) < 0) goto error; done: if (cond_normalise(ctx, lhs ? lhs->quote : T_INVALID, &c) < 0) { talloc_free(c); - return 0; + fr_sbuff_set_to_start(&our_in); + return fr_sbuff_error(&our_in); } *out = c; diff --git a/src/lib/server/map.c b/src/lib/server/map.c index 7496693083f..1b8b1ac16ac 100644 --- a/src/lib/server/map.c +++ b/src/lib/server/map.c @@ -469,7 +469,7 @@ ssize_t map_afrom_substr(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, fr_sbuf error_adj: talloc_free(map); - FR_SBUFF_ERROR_RETURN_ADJ(&our_in, slen); + FR_SBUFF_ERROR_RETURN(&our_in); } /* diff --git a/src/lib/server/tmpl_dcursor_tests.c b/src/lib/server/tmpl_dcursor_tests.c index 2c4b4469d82..24382049a28 100644 --- a/src/lib/server/tmpl_dcursor_tests.c +++ b/src/lib/server/tmpl_dcursor_tests.c @@ -123,6 +123,8 @@ static request_t *request_fake_alloc(void) do { \ char const *ref = _attr_str; \ tmpl_afrom_attr_substr(autofree, NULL, &vpt, &FR_SBUFF_IN(ref, strlen(ref)), NULL, &(tmpl_rules_t){.attr = {.dict_def = test_dict}}); \ + TEST_CHECK(vpt != NULL); \ + TEST_MSG("Failed creating tmpl from %s: %s", ref, fr_strerror()); \ *(_out) = tmpl_dcursor_init(&err, NULL, &cc, &cursor, request, vpt); \ } while (0) diff --git a/src/lib/server/tmpl_tokenize.c b/src/lib/server/tmpl_tokenize.c index b81ec321f0c..c974bf42784 100644 --- a/src/lib/server/tmpl_tokenize.c +++ b/src/lib/server/tmpl_tokenize.c @@ -1533,7 +1533,6 @@ static inline int tmpl_attr_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t unsigned int depth) { uint32_t oid = 0; - ssize_t slen; tmpl_attr_t *ar = NULL; fr_dict_attr_t const *da; fr_sbuff_marker_t m_s; @@ -1563,11 +1562,11 @@ static inline int tmpl_attr_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t * No parent means we need to go hunting through all the dictionaries */ if (!our_parent) { - slen = fr_dict_attr_search_by_qualified_name_substr(&dict_err, &da, - t_rules->dict_def, - name, p_rules ? p_rules->terminals : NULL, - !t_rules->disallow_internal, - t_rules->allow_foreign); + (void)fr_dict_attr_search_by_qualified_name_substr(&dict_err, &da, + t_rules->dict_def, + name, p_rules ? p_rules->terminals : NULL, + !t_rules->disallow_internal, + t_rules->allow_foreign); /* * We can't know which dictionary the * attribute will be resolved in, so the @@ -1580,11 +1579,11 @@ static inline int tmpl_attr_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t * or its reference in the case of group attributes. */ } else { - slen = fr_dict_attr_by_name_substr(&dict_err, - &da, - namespace, - name, - p_rules ? p_rules->terminals : NULL); + (void)fr_dict_attr_by_name_substr(&dict_err, + &da, + namespace, + name, + p_rules ? p_rules->terminals : NULL); /* * Allow fallback to internal attributes * if the parent was a group, and we're @@ -1613,11 +1612,9 @@ static inline int tmpl_attr_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t switch (dict_err) { case FR_DICT_ATTR_NO_CHILDREN: if (our_parent && our_parent->flags.is_unknown) break; - fr_sbuff_advance(name, slen * -1); goto error; case FR_DICT_ATTR_NOT_DESCENDENT: - fr_sbuff_advance(name, slen * -1); goto error; default: @@ -1704,7 +1701,6 @@ static inline int tmpl_attr_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t } MEM(ar = talloc(ctx, tmpl_attr_t)); - switch (namespace->type) { case FR_TYPE_VSA: da_unknown = fr_dict_unknown_vendor_afrom_num(ar, namespace, oid); @@ -2317,21 +2313,19 @@ static fr_slen_t tmpl_afrom_value_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff fr_sbuff_t our_in = FR_SBUFF(in); fr_value_box_t tmp; tmpl_t *vpt; - fr_slen_t slen; if (!fr_type_is_leaf(t_rules->cast)) { fr_strerror_printf("%s is not a valid cast type", fr_type_to_str(t_rules->cast)); - return 0; + return fr_sbuff_error(&our_in); } vpt = tmpl_alloc_null(ctx); - slen = fr_value_box_from_substr(vpt, &tmp, - t_rules->cast, allow_enum ? t_rules->enumv : NULL, - &our_in, p_rules, false); - if (slen < 0) { + if (fr_value_box_from_substr(vpt, &tmp, + t_rules->cast, allow_enum ? t_rules->enumv : NULL, + &our_in, p_rules, false) < 0) { talloc_free(vpt); - return slen; + return fr_sbuff_error(&our_in); } tmpl_init(vpt, TMPL_TYPE_DATA, quote, fr_sbuff_start(&our_in), fr_sbuff_used(&our_in), t_rules); @@ -2354,11 +2348,11 @@ static fr_slen_t tmpl_afrom_value_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff * @param[in] in sbuff to parse. * @param[in] p_rules formatting rules. * @return - * - 0 sbuff does not contain a boolean value. + * - < 0 sbuff does not contain a boolean value. * - > 0 how many bytes were parsed. */ -static ssize_t tmpl_afrom_bool_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules) +static fr_slen_t tmpl_afrom_bool_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, + fr_sbuff_parse_rules_t const *p_rules) { fr_sbuff_t our_in = FR_SBUFF(in); bool a_bool; @@ -2371,7 +2365,7 @@ static ssize_t tmpl_afrom_bool_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t if (!tmpl_substr_terminal_check(&our_in, p_rules)) { fr_strerror_const("Unexpected text after bool"); - return -fr_sbuff_used(in); + return fr_sbuff_error(in); } MEM(vpt = tmpl_alloc(ctx, TMPL_TYPE_DATA, T_BARE_WORD, fr_sbuff_start(&our_in), fr_sbuff_used(&our_in))); @@ -2395,8 +2389,8 @@ static ssize_t tmpl_afrom_bool_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t * - 0 sbuff does not contain a hex string. * - > 0 how many bytes were parsed. */ -static ssize_t tmpl_afrom_octets_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules) +static fr_slen_t tmpl_afrom_octets_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, + fr_sbuff_parse_rules_t const *p_rules) { fr_sbuff_t our_in = FR_SBUFF(in); tmpl_t *vpt; @@ -2418,7 +2412,7 @@ static ssize_t tmpl_afrom_octets_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_ fr_strerror_const("Hex string not even length"); error: talloc_free(vpt); - return -fr_sbuff_used(&our_in); + return fr_sbuff_error(&our_in); } if (len == 0) { fr_strerror_const("Zero length hex string is invalid"); @@ -2451,11 +2445,11 @@ static ssize_t tmpl_afrom_octets_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_ * @param[in] in sbuff to parse. * @param[in] p_rules formatting rules. * @return - * - 0 sbuff does not contain an IPv4 address or prefix. + * - < 0 sbuff does not contain an IPv4 address or prefix. * - > 0 how many bytes were parsed. */ -static ssize_t tmpl_afrom_ipv4_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules) +static fr_slen_t tmpl_afrom_ipv4_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, + fr_sbuff_parse_rules_t const *p_rules) { tmpl_t *vpt; fr_sbuff_t our_in = FR_SBUFF(in); @@ -2472,7 +2466,7 @@ static ssize_t tmpl_afrom_ipv4_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t fr_sbuff_out(NULL, &octet, &our_in) && fr_sbuff_next_if_char(&our_in, '.') && fr_sbuff_out(NULL, &octet, &our_in))) { error: - return -fr_sbuff_used(&our_in); + return fr_sbuff_error(&our_in); } /* @@ -2519,11 +2513,11 @@ static ssize_t tmpl_afrom_ipv4_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t * @param[in] in sbuff to parse. * @param[in] p_rules formatting rules. * @return - * - 0 sbuff does not contain an IPv4 address or prefix. + * - < 0 sbuff does not contain an IPv4 address or prefix. * - > 0 how many bytes were parsed. */ -static ssize_t tmpl_afrom_ipv6_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules) +static fr_slen_t tmpl_afrom_ipv6_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, + fr_sbuff_parse_rules_t const *p_rules) { tmpl_t *vpt; fr_sbuff_t our_in = FR_SBUFF(in); @@ -2556,7 +2550,7 @@ static ssize_t tmpl_afrom_ipv6_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t len = fr_sbuff_adv_past_allowed(&our_in, FR_IPADDR_STRLEN + 1, ipv6_chars, NULL); if ((len < 2) || (len > FR_IPADDR_STRLEN)) { error: - return -fr_sbuff_used(&our_in); + return fr_sbuff_error(&our_in); } /* @@ -2637,7 +2631,7 @@ static ssize_t tmpl_afrom_ipv6_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t * @param[in] in sbuff to parse. * @param[in] p_rules formatting rules. * @return - * - 0 sbuff does not contain a mac address. + * - < 0 sbuff does not contain a mac address. * - > 0 how many bytes were parsed. */ static ssize_t tmpl_afrom_ether_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, @@ -2705,11 +2699,11 @@ static ssize_t tmpl_afrom_ether_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t * @param[in] in sbuff to parse. * @param[in] p_rules formatting rules. * @return - * - 0 sbuff does not contain an integer. + * - < 0 sbuff does not contain an integer. * - > 0 how many bytes were parsed. */ -static ssize_t tmpl_afrom_integer_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules) +static fr_slen_t tmpl_afrom_integer_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, + fr_sbuff_parse_rules_t const *p_rules) { tmpl_t *vpt; fr_sbuff_t our_in = FR_SBUFF(in); @@ -2728,7 +2722,7 @@ static ssize_t tmpl_afrom_integer_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff if (!tmpl_substr_terminal_check(&our_in, p_rules)) { fr_strerror_const("Unexpected text after signed integer"); error: - return -fr_sbuff_used(&our_in); + return fr_sbuff_error(&our_in); } MEM(vpt = tmpl_alloc(ctx, TMPL_TYPE_DATA, @@ -2862,10 +2856,10 @@ static ssize_t tmpl_afrom_time_delta(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t * * * @see tmpl_afrom_attr_substr */ -ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, - fr_sbuff_t *in, fr_token_t quote, - fr_sbuff_parse_rules_t const *p_rules, - tmpl_rules_t const *t_rules) +fr_slen_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, + fr_sbuff_t *in, fr_token_t quote, + fr_sbuff_parse_rules_t const *p_rules, + tmpl_rules_t const *t_rules) { fr_sbuff_t our_in = FR_SBUFF(in); @@ -2905,7 +2899,7 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, p_rules, t_rules); } - if (!head) return slen; + if (slen < 0) return fr_sbuff_error(&our_in); if (xlat_needs_resolving(head)) UNRESOLVED_SET(&type); @@ -3012,8 +3006,7 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, * of bareword, assume it's an enum * value. */ - slen = fr_dict_enum_name_afrom_substr(vpt, &str, &sberr, &our_in, p_rules ? p_rules->terminals : NULL); - if (slen < 0) { + if (fr_dict_enum_name_afrom_substr(vpt, &str, &sberr, &our_in, p_rules ? p_rules->terminals : NULL) < 0) { /* * Produce our own errors which make * more sense in the context of tmpls @@ -3034,7 +3027,7 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, } bareword_error: talloc_free(vpt); - return slen; + return fr_sbuff_error(&our_in); } /* @@ -3098,7 +3091,7 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, slen = xlat_tokenize_ephemeral(vpt, &head, t_rules->xlat.runtime_el, &our_in, p_rules, t_rules); } - if (!head) return slen; + if (slen < 0) return fr_sbuff_error(&our_in); /* * If the string doesn't contain an xlat, @@ -3157,9 +3150,8 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, */ slen = xlat_tokenize_argv(vpt, &head, &our_in, p_rules, t_rules); if (slen < 0) { - fr_sbuff_advance(&our_in, slen * -1); talloc_free(vpt); - return slen; + return fr_sbuff_error(&our_in); } if (xlat_needs_resolving(head)) UNRESOLVED_SET(&type); @@ -3171,13 +3163,13 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, case T_SOLIDUS_QUOTED_STRING: { - xlat_exp_head_t *head = NULL; tmpl_type_t type = TMPL_TYPE_REGEX_XLAT; if (!fr_type_is_null(t_rules->cast)) { fr_strerror_const("Casts cannot be used with regular expressions"); - return -1; + fr_sbuff_set_to_start(&our_in); /* Point to the cast */ + FR_SBUFF_ERROR_RETURN(&our_in); } vpt = tmpl_alloc_null(ctx); @@ -3190,7 +3182,7 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, p_rules, t_rules); } - if (!head) return slen; + if (slen < 0) return fr_sbuff_error(&our_in); /* * Check if the string actually contains an xlat @@ -3222,7 +3214,7 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, default: fr_assert(0); - return 0; /* 0 is an error here too */ + return fr_sbuff_error(&our_in); } TMPL_VERIFY(vpt); @@ -3456,8 +3448,8 @@ done: */ ssize_t tmpl_regex_flags_substr(tmpl_t *vpt, fr_sbuff_t *in, fr_sbuff_term_t const *terminals) { - ssize_t slen; - int err = 0; + fr_slen_t slen; + int err = 0; fr_assert(tmpl_is_regex_uncompiled(vpt) || tmpl_is_regex_xlat(vpt) || tmpl_is_regex_xlat_unresolved(vpt)); diff --git a/src/lib/unlang/xlat.h b/src/lib/unlang/xlat.h index 44052de623e..fbfb5a24f4f 100644 --- a/src/lib/unlang/xlat.h +++ b/src/lib/unlang/xlat.h @@ -291,28 +291,28 @@ int xlat_flatten_compiled_argv(TALLOC_CTX *ctx, xlat_exp_head_t ***argv, xlat_e bool xlat_async_required(xlat_exp_head_t const *xlat); -ssize_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in, +fr_slen_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules); -ssize_t xlat_tokenize_condition(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in, +fr_slen_t xlat_tokenize_condition(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules); -ssize_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_head_t **head, +fr_slen_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_event_list_t *el, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules); -ssize_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_head_t **head, +fr_slen_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_event_list_t *el, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules); -ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in, +fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules); -ssize_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in, +fr_slen_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules); -ssize_t xlat_print(fr_sbuff_t *in, xlat_exp_head_t const *node, fr_sbuff_escape_rules_t const *e_rules); +fr_slen_t xlat_print(fr_sbuff_t *in, xlat_exp_head_t const *node, fr_sbuff_escape_rules_t const *e_rules); static inline fr_slen_t xlat_aprint(TALLOC_CTX *ctx, char **out, xlat_exp_head_t const *head, fr_sbuff_escape_rules_t const *e_rules) diff --git a/src/lib/unlang/xlat_expr.c b/src/lib/unlang/xlat_expr.c index 9bef82b66e9..c96a9e02df5 100644 --- a/src/lib/unlang/xlat_expr.c +++ b/src/lib/unlang/xlat_expr.c @@ -1858,11 +1858,10 @@ static size_t expr_quote_table_len = NUM_ELEMENTS(expr_quote_table); * to parse the next thing we get. Otherwise, parse the thing as * int64_t. */ -static ssize_t tokenize_unary(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, - fr_sbuff_parse_rules_t const *bracket_rules, char *out_c, bool cond) +static fr_slen_t tokenize_unary(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, + fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, + fr_sbuff_parse_rules_t const *bracket_rules, char *out_c, bool cond) { - ssize_t slen; xlat_exp_t *node = NULL, *unary = NULL; xlat_t *func = NULL; fr_sbuff_t our_in = FR_SBUFF(in); @@ -1909,9 +1908,9 @@ static ssize_t tokenize_unary(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_ check_for_double: fr_sbuff_skip_whitespace(&our_in); fr_sbuff_skip_whitespace(&our_in); - if (fr_sbuff_next_if_char(&our_in, c)) { + if (fr_sbuff_is_char(&our_in, c)) { fr_strerror_const("Double operator is invalid"); - return (-fr_sbuff_used(&our_in) + 1); + return fr_sbuff_error(&our_in); } } @@ -1935,15 +1934,14 @@ static ssize_t tokenize_unary(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_ unary->call.func = func; unary->flags = func->flags; - slen = tokenize_field(unary->call.args, &node, &our_in, p_rules, t_rules, bracket_rules, out_c, (c == '!')); - if (slen < 0) { + if (tokenize_field(unary->call.args, &node, &our_in, p_rules, t_rules, bracket_rules, out_c, (c == '!')) < 0) { talloc_free(unary); - FR_SBUFF_ERROR_RETURN_ADJ(&our_in, slen); + FR_SBUFF_ERROR_RETURN(&our_in); } if (!node) { fr_strerror_const("Empty expression is invalid"); - FR_SBUFF_ERROR_RETURN_ADJ(&our_in, -slen); + FR_SBUFF_ERROR_RETURN(&our_in); } /* @@ -1955,7 +1953,7 @@ static ssize_t tokenize_unary(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_ */ if (reparse_rcode(head, &node, (c == '!')) < 0) { talloc_free(unary); - FR_SBUFF_ERROR_RETURN_ADJ(&our_in, -slen); + FR_SBUFF_ERROR_RETURN(&our_in); } xlat_func_append_arg(unary, node, (c == '!')); @@ -2011,7 +2009,7 @@ static xlat_exp_t *expr_cast_alloc(TALLOC_CTX *ctx, fr_type_t type) return cast; } -static ssize_t expr_cast_from_substr(fr_type_t *cast, fr_sbuff_t *in) +static fr_slen_t expr_cast_from_substr(fr_type_t *cast, fr_sbuff_t *in) { char close = '\0'; fr_sbuff_t our_in = FR_SBUFF(in); @@ -2036,12 +2034,12 @@ static ssize_t expr_cast_from_substr(fr_type_t *cast, fr_sbuff_t *in) if (!fr_type_is_leaf(*cast)) { fr_strerror_printf("Invalid data type '%s' in cast", fr_type_to_str(*cast)); - return -1; + return fr_sbuff_error(&our_in) } if (!fr_sbuff_next_if_char(&our_in, close)) { fr_strerror_const("Unterminated cast"); - return -1; + return fr_sbuff_error(&our_in) } fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX, NULL); @@ -2051,9 +2049,9 @@ static ssize_t expr_cast_from_substr(fr_type_t *cast, fr_sbuff_t *in) /* * Tokenize the RHS of a regular expression. */ -static ssize_t tokenize_regex_rhs(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, - tmpl_rules_t const *t_rules, - fr_sbuff_parse_rules_t const *bracket_rules) +static fr_slen_t tokenize_regex_rhs(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, + tmpl_rules_t const *t_rules, + fr_sbuff_parse_rules_t const *bracket_rules) { ssize_t slen; xlat_exp_t *node = NULL; @@ -2101,8 +2099,7 @@ static ssize_t tokenize_regex_rhs(xlat_exp_head_t *head, xlat_exp_t **out, fr_sb if (!vpt) { error: talloc_free(node); - fr_sbuff_set(&our_in, &opand_m); - return -fr_sbuff_used(&our_in); + return fr_sbuff_error(&our_in); } /* @@ -2121,12 +2118,9 @@ static ssize_t tokenize_regex_rhs(xlat_exp_head_t *head, xlat_exp_t **out, fr_sb * Remember where the flags start */ fr_sbuff_marker(&flag, &our_in); - slen = tmpl_regex_flags_substr(vpt, &our_in, bracket_rules->terminals); - if (slen < 0) { + if (tmpl_regex_flags_substr(vpt, &our_in, bracket_rules->terminals) < 0) { talloc_free(node); - fr_sbuff_set(&our_in, &flag); - fr_sbuff_advance(&our_in, -slen); - return -fr_sbuff_used(&our_in); + return fr_sbuff_error(&our_in); } fr_sbuff_skip_whitespace(&our_in); @@ -2156,9 +2150,9 @@ static ssize_t tokenize_regex_rhs(xlat_exp_head_t *head, xlat_exp_t **out, fr_sb /* * Tokenize a field without unary operators. */ -static ssize_t tokenize_field(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, - fr_sbuff_parse_rules_t const *bracket_rules, char *out_c, bool cond) +static fr_slen_t tokenize_field(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, + fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, + fr_sbuff_parse_rules_t const *bracket_rules, char *out_c, bool cond) { ssize_t slen; xlat_exp_t *node = NULL; @@ -2198,16 +2192,15 @@ static ssize_t tokenize_field(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_ * No input rules means "ignore external terminal sequences, as we're expecting a ')' as * our terminal sequence. */ - slen = tokenize_expression(my_head, &node, &our_in, bracket_rules, t_rules, T_INVALID, bracket_rules, NULL, cond); - if (slen <= 0) { + if (tokenize_expression(my_head, &node, &our_in, bracket_rules, t_rules, T_INVALID, bracket_rules, NULL, cond) < 0) { talloc_free(cast); - FR_SBUFF_ERROR_RETURN_ADJ(&our_in, slen); + FR_SBUFF_ERROR_RETURN(&our_in); } if (!fr_sbuff_next_if_char(&our_in, ')')) { talloc_free(cast); fr_strerror_printf("Failed to find trailing ')'"); - FR_SBUFF_ERROR_RETURN_ADJ(&our_in, -slen); + FR_SBUFF_ERROR_RETURN(&our_in); } /* @@ -2264,21 +2257,15 @@ static ssize_t tokenize_field(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_ * our_t_rules, and will try to parse any data there as * of the correct type. */ - slen = tmpl_afrom_substr(node, &vpt, &our_in, quote, p_rules, &our_t_rules); - if (!vpt) { - fr_sbuff_advance(&our_in, slen * -1); - + if (tmpl_afrom_substr(node, &vpt, &our_in, quote, p_rules, &our_t_rules) < 0) { error: - return -fr_sbuff_used(&our_in); + return fr_sbuff_error(&our_in); } - /* - * It would be nice if tmpl_afrom_substr() did this :( - */ if (quote != T_BARE_WORD) { if (!fr_sbuff_is_char(&our_in, fr_token_quote[quote])) { fr_strerror_const("Unterminated string"); - fr_sbuff_advance(&our_in, slen * -1); + fr_sbuff_set(&our_in, &opand_m); goto error; } @@ -2470,10 +2457,10 @@ static bool valid_type(xlat_exp_t *node) * If "out" is NULL then the expression is added to "head". * Otherwise, it's returned to the caller. */ -static ssize_t tokenize_expression(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, - fr_token_t prev, fr_sbuff_parse_rules_t const *bracket_rules, - fr_sbuff_parse_rules_t const *input_rules, bool cond) +static fr_slen_t tokenize_expression(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, + fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, + fr_token_t prev, fr_sbuff_parse_rules_t const *bracket_rules, + fr_sbuff_parse_rules_t const *input_rules, bool cond) { xlat_exp_t *lhs = NULL, *rhs, *node; xlat_t *func = NULL; @@ -2494,7 +2481,7 @@ static ssize_t tokenize_expression(xlat_exp_head_t *head, xlat_exp_t **out, fr_s * Get the LHS of the operation. */ slen = tokenize_unary(head, &lhs, &our_in, p_rules, t_rules, bracket_rules, &c, cond); - if (slen < 0) return slen; + if (slen < 0) return fr_sbuff_error(&our_in); if (slen == 0) { fr_assert(lhs == NULL); @@ -2563,7 +2550,7 @@ redo: if (!binary_ops[op].str) { fr_strerror_printf("Invalid operator"); fr_sbuff_set(&our_in, &m_op); - return -fr_sbuff_used(&our_in); + return fr_sbuff_error(&our_in); } fr_assert(precedence[op] != 0); @@ -2586,7 +2573,7 @@ redo: fr_strerror_printf("Operator '%c' is only applied to the left hand side of the '%s' operation, add (..) to evaluate the operation first", c, fr_tokens[op]); fail_lhs: fr_sbuff_set(&our_in, &m_lhs); - return -fr_sbuff_used(&our_in); + return fr_sbuff_error(&our_in); } fr_sbuff_skip_whitespace(&our_in); @@ -2604,7 +2591,7 @@ redo: if ((op != T_OP_CMP_EQ) && (op != T_OP_NE)) { fr_strerror_printf("Invalid operatord '%s' for left hand side structural attribute", fr_tokens[op]); fr_sbuff_set(&our_in, &m_op); - return -fr_sbuff_used(&our_in); + return fr_sbuff_error(&our_in); } fr_assert(0); @@ -2620,9 +2607,9 @@ redo: } else { slen = tokenize_expression(head, &rhs, &our_in, p_rules, t_rules, op, bracket_rules, input_rules, cond); } - if (slen <= 0) { + if (slen < 0) { talloc_free(lhs); - FR_SBUFF_ERROR_RETURN_ADJ(&our_in, slen); + FR_SBUFF_ERROR_RETURN(&our_in); } #ifdef STATIC_ANALYZER @@ -2640,7 +2627,7 @@ redo: if (reparse_rcode(head, &rhs, true) < 0) { fail_rhs: fr_sbuff_set(&our_in, &m_rhs); - return -fr_sbuff_used(&our_in); + return fr_sbuff_error(&our_in); } if ((lhs->type == XLAT_FUNC) && (lhs->call.func->token == op)) { @@ -2745,8 +2732,8 @@ static const fr_sbuff_term_t operator_terms = FR_SBUFF_TERMS( L("~"), ); -static ssize_t xlat_tokenize_expression_internal(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, bool cond) +static fr_slen_t xlat_tokenize_expression_internal(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in, + fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, bool cond) { ssize_t slen; fr_sbuff_parse_rules_t *bracket_rules = NULL; @@ -2793,7 +2780,7 @@ static ssize_t xlat_tokenize_expression_internal(TALLOC_CTX *ctx, xlat_exp_head_ if (slen < 0) { talloc_free(head); - return slen; + FR_SBUFF_ERROR_RETURN(in); } if (!node) { @@ -2806,7 +2793,7 @@ static ssize_t xlat_tokenize_expression_internal(TALLOC_CTX *ctx, xlat_exp_head_ */ if (reparse_rcode(head, &node, true) < 0) { talloc_free(head); - return 0; + return -1; } /* @@ -2824,20 +2811,20 @@ static ssize_t xlat_tokenize_expression_internal(TALLOC_CTX *ctx, xlat_exp_head_ */ if (xlat_bootstrap(head) < 0) { talloc_free(head); - return 0; + return -1; } *out = head; return slen; } -ssize_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in, +fr_slen_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) { return xlat_tokenize_expression_internal(ctx, out, in, p_rules, t_rules, false); } -ssize_t xlat_tokenize_condition(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in, +fr_slen_t xlat_tokenize_condition(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) { return xlat_tokenize_expression_internal(ctx, out, in, p_rules, t_rules, true); @@ -2861,9 +2848,9 @@ ssize_t xlat_tokenize_condition(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff * - 0 and *head != NULL - Zero length expansion * - <0 the negative offset of the parse failure. */ -ssize_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_head_t **out, - fr_event_list_t *el, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) +fr_slen_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_head_t **out, + fr_event_list_t *el, fr_sbuff_t *in, + fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) { ssize_t slen; fr_sbuff_parse_rules_t *bracket_rules = NULL; @@ -2913,7 +2900,7 @@ ssize_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_head_t **ou if (slen < 0) { talloc_free(head); - return slen; + FR_SBUFF_ERROR_RETURN(in); } if (!node) { @@ -2926,7 +2913,7 @@ ssize_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_head_t **ou */ if (reparse_rcode(head, &node, true) < 0) { talloc_free(head); - return 0; + return -1; } xlat_exp_insert_tail(head, node); @@ -2936,7 +2923,7 @@ ssize_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_head_t **ou */ if (xlat_instantiate_ephemeral(head, el) < 0) { talloc_free(head); - return 0; + return -1; } *out = head; diff --git a/src/lib/unlang/xlat_tokenize.c b/src/lib/unlang/xlat_tokenize.c index 60baa525424..5f92723bb8e 100644 --- a/src/lib/unlang/xlat_tokenize.c +++ b/src/lib/unlang/xlat_tokenize.c @@ -615,7 +615,6 @@ static int xlat_resolve_virtual_attribute(xlat_exp_t *node, tmpl_t *vpt) static inline int xlat_tokenize_attribute(xlat_exp_head_t *head, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) { - ssize_t slen; tmpl_attr_error_t err; tmpl_t *vpt = NULL; xlat_exp_t *node; @@ -646,10 +645,7 @@ static inline int xlat_tokenize_attribute(xlat_exp_head_t *head, fr_sbuff_t *in, fr_sbuff_marker(&m_s, in); MEM(node = xlat_exp_alloc_null(head)); - slen = tmpl_afrom_attr_substr(node, &err, &vpt, in, p_rules, &our_t_rules); - if (slen <= 0) { - fr_sbuff_advance(in, slen * -1); - + if (tmpl_afrom_attr_substr(node, &err, &vpt, in, p_rules, &our_t_rules) < 0) { /* * If the parse error occurred before the ':' * then the error is changed to 'Unknown module', @@ -660,7 +656,7 @@ static inline int xlat_tokenize_attribute(xlat_exp_head_t *head, fr_sbuff_t *in, error: fr_sbuff_marker_release(&m_s); talloc_free(node); - return -1; + return fr_sbuff_error(in); } /* @@ -1428,9 +1424,9 @@ ssize_t xlat_print(fr_sbuff_t *out, xlat_exp_head_t const *head, fr_sbuff_escape * - 0 and *head != NULL - Zero length expansion * - <0 the negative offset of the parse failure. */ -ssize_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_head_t **out, - fr_event_list_t *el, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) +fr_slen_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_head_t **out, + fr_event_list_t *el, fr_sbuff_t *in, + fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) { fr_sbuff_t our_in = FR_SBUFF(in); tmpl_rules_t our_t_rules = {}; @@ -1449,7 +1445,7 @@ ssize_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_head_t **out, if (xlat_tokenize_string(head, &our_in, false, p_rules, &our_t_rules) < 0) { talloc_free(head); - return -fr_sbuff_used(&our_in); + return fr_sbuff_error(&our_in); } /* @@ -1486,11 +1482,11 @@ ssize_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_head_t **out, * any expansions. * @param[in] t_rules controlling how attribute references are parsed. * @return - * - <=0 on error. + * - < 0 on error. * - >0 on success which is the number of characters parsed. */ -ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) +fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in, + fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) { fr_sbuff_t our_in = FR_SBUFF(in); ssize_t slen; @@ -1553,7 +1549,7 @@ ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *i } talloc_free(head); - return -fr_sbuff_used(&our_in); /* error */ + return fr_sbuff_error(&our_in); /* error */ } break; @@ -1657,8 +1653,8 @@ ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *i * - 0 and *head != NULL - Zero length expansion * - < 0 the negative offset of the parse failure. */ -ssize_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) +fr_slen_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in, + fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) { fr_sbuff_t our_in = FR_SBUFF(in); xlat_exp_head_t *head; @@ -1671,7 +1667,7 @@ ssize_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in, if (xlat_tokenize_string(head, &our_in, false, p_rules, t_rules) < 0) { talloc_free(head); - return -fr_sbuff_used(&our_in); + return fr_sbuff_error(&our_in); } /* diff --git a/src/lib/util/base16.c b/src/lib/util/base16.c index 4eeeb455c65..51471fc44ef 100644 --- a/src/lib/util/base16.c +++ b/src/lib/util/base16.c @@ -112,7 +112,7 @@ uint8_t const fr_base16_alphabet_decode_mc[UINT8_MAX + 1] = { * - >=0 the number of bytes written to out. * - <0 number of bytes we would have needed to print the next hexit. */ -ssize_t fr_base16_encode_nstd(fr_sbuff_t *out, fr_dbuff_t *in, char const alphabet[static UINT8_MAX + 1]) +fr_slen_t fr_base16_encode_nstd(fr_sbuff_t *out, fr_dbuff_t *in, char const alphabet[static UINT8_MAX + 1]) { fr_sbuff_t our_out = FR_SBUFF(out); fr_dbuff_t our_in = FR_DBUFF(in); diff --git a/src/lib/util/base16.h b/src/lib/util/base16.h index 917b0a7a04f..f5638f80ae3 100644 --- a/src/lib/util/base16.h +++ b/src/lib/util/base16.h @@ -53,7 +53,7 @@ static inline bool fr_is_base16_nstd(char c, uint8_t const alphabet[static UINT8 return alphabet[(uint8_t)c] < 16; } -ssize_t fr_base16_encode_nstd(fr_sbuff_t *out, fr_dbuff_t *in, char const alphabet[static UINT8_MAX + 1]); +fr_slen_t fr_base16_encode_nstd(fr_sbuff_t *out, fr_dbuff_t *in, char const alphabet[static UINT8_MAX + 1]); #define fr_base16_encode(_out, _in) \ fr_base16_encode_nstd(_out, _in, fr_base16_alphabet_encode_lc) @@ -68,7 +68,7 @@ ssize_t fr_base16_encode_nstd(fr_sbuff_t *out, fr_dbuff_t *in, char const alpha * - >=0 the number of bytes written to out. * - <0 number of bytes we would have needed to print the next hexit. */ -static inline ssize_t fr_base16_aencode(TALLOC_CTX *ctx, char **out, fr_dbuff_t *in) +static inline fr_slen_t fr_base16_aencode(TALLOC_CTX *ctx, char **out, fr_dbuff_t *in) { fr_sbuff_t sbuff; fr_sbuff_uctx_talloc_t tctx; @@ -79,10 +79,10 @@ static inline ssize_t fr_base16_aencode(TALLOC_CTX *ctx, char **out, fr_dbuff_t SIZE_MAX); slen = fr_base16_encode(&sbuff, in); - if (slen <= 0) { + if (slen < 0) { fr_sbuff_trim_talloc(&sbuff, 0); *out = sbuff.buff; - return 0; + return slen; } *out = sbuff.buff; @@ -90,7 +90,7 @@ static inline ssize_t fr_base16_aencode(TALLOC_CTX *ctx, char **out, fr_dbuff_t return (size_t)slen; } -ssize_t fr_base16_decode_nstd(fr_sbuff_parse_error_t *err, fr_dbuff_t *out, fr_sbuff_t *in, +fr_slen_t fr_base16_decode_nstd(fr_sbuff_parse_error_t *err, fr_dbuff_t *out, fr_sbuff_t *in, bool no_trailing, uint8_t const alphabet[static UINT8_MAX + 1]); #define fr_base16_decode(_err, _out, _in, _no_trailing) \ fr_base16_decode_nstd(_err, _out, _in, _no_trailing, fr_base16_alphabet_decode_mc) diff --git a/src/lib/util/dict.h b/src/lib/util/dict.h index 5cf38743be0..5b4aa2d3f4c 100644 --- a/src/lib/util/dict.h +++ b/src/lib/util/dict.h @@ -384,7 +384,7 @@ fr_dict_attr_t *fr_dict_unknown_afrom_fields(TALLOC_CTX *ctx, unsigned int vendor, unsigned int attr) CC_HINT(nonnull(2)); -ssize_t fr_dict_unknown_afrom_oid_substr(TALLOC_CTX *ctx, +fr_slen_t fr_dict_unknown_afrom_oid_substr(TALLOC_CTX *ctx, fr_dict_attr_err_t *err, fr_dict_attr_t **out, fr_dict_attr_t const *parent, fr_sbuff_t *in, fr_sbuff_term_t const *tt) @@ -449,22 +449,22 @@ fr_dict_attr_t const *fr_dict_attr_common_parent(fr_dict_attr_t const *a, fr_dic int fr_dict_oid_component_legacy(unsigned int *out, char const **oid); -ssize_t fr_dict_attr_flags_print(fr_sbuff_t *out, fr_dict_t const *dict, +fr_slen_t fr_dict_attr_flags_print(fr_sbuff_t *out, fr_dict_t const *dict, fr_type_t type, fr_dict_attr_flags_t const *flags); -ssize_t fr_dict_attr_oid_print(fr_sbuff_t *out, +fr_slen_t fr_dict_attr_oid_print(fr_sbuff_t *out, fr_dict_attr_t const *ancestor, fr_dict_attr_t const *da, bool numeric); #define FR_DICT_ATTR_OID_PRINT_RETURN(...) FR_SBUFF_RETURN(fr_dict_attr_oid_print, ##__VA_ARGS__) -ssize_t fr_dict_attr_by_oid_legacy(fr_dict_t const *dict, fr_dict_attr_t const **parent, +fr_slen_t fr_dict_attr_by_oid_legacy(fr_dict_t const *dict, fr_dict_attr_t const **parent, unsigned int *attr, char const *oid) CC_HINT(nonnull); -ssize_t fr_dict_oid_component(fr_dict_attr_err_t *err, +fr_slen_t fr_dict_oid_component(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_attr_t const *parent, fr_sbuff_t *in, fr_sbuff_term_t const *tt) CC_HINT(nonnull(2,3,4)); -ssize_t fr_dict_attr_by_oid_substr(fr_dict_attr_err_t *err, +fr_slen_t fr_dict_attr_by_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_attr_t const *parent, fr_sbuff_t *in, fr_sbuff_term_t const *tt) CC_HINT(nonnull(2,3,4)); @@ -489,7 +489,7 @@ bool fr_dict_is_read_only(fr_dict_t const *dict); dl_t *fr_dict_dl(fr_dict_t const *dict); -ssize_t fr_dict_by_protocol_substr(fr_dict_attr_err_t *err, +fr_slen_t fr_dict_by_protocol_substr(fr_dict_attr_err_t *err, fr_dict_t const **out, fr_sbuff_t *name, fr_dict_t const *dict_def); fr_dict_t const *fr_dict_by_protocol_name(char const *name); @@ -521,19 +521,19 @@ fr_dict_vendor_t const *fr_dict_vendor_by_num(fr_dict_t const *dict, uint32_t ve fr_dict_attr_t const *fr_dict_vendor_da_by_num(fr_dict_attr_t const *vendor_root, uint32_t vendor_pen); -ssize_t fr_dict_attr_search_by_qualified_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, +fr_slen_t fr_dict_attr_search_by_qualified_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_t const *dict_def, fr_sbuff_t *name, fr_sbuff_term_t const *tt, bool internal, bool foreign) CC_HINT(nonnull(2, 4)); -ssize_t fr_dict_attr_search_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, +fr_slen_t fr_dict_attr_search_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_t const *dict_def, fr_sbuff_t *name, fr_sbuff_term_t const *tt, bool internal, bool foreign) CC_HINT(nonnull(2, 4)); -ssize_t fr_dict_attr_search_by_qualified_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, +fr_slen_t fr_dict_attr_search_by_qualified_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_t const *dict_def, fr_sbuff_t *in, fr_sbuff_term_t const *tt, bool internal, bool foreign) @@ -544,13 +544,13 @@ fr_dict_attr_t const *fr_dict_attr_search_by_qualified_oid(fr_dict_attr_err_t *e bool internal, bool foreign) CC_HINT(nonnull(3)); -ssize_t fr_dict_attr_search_by_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, +fr_slen_t fr_dict_attr_search_by_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_t const *dict_def, fr_sbuff_t *in, fr_sbuff_term_t const *tt, bool internal, bool foreign) CC_HINT(nonnull(2, 4)); -ssize_t fr_dict_attr_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, +fr_slen_t fr_dict_attr_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, fr_dict_attr_t const *parent, fr_sbuff_t *name, fr_sbuff_term_t const *tt) CC_HINT(nonnull(2,3,4)); @@ -567,7 +567,7 @@ char const *fr_dict_enum_name_by_value(fr_dict_attr_t const *da, fr_value_box_t fr_dict_enum_value_t *fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len); -ssize_t fr_dict_enum_by_name_substr(fr_dict_enum_value_t **out, fr_dict_attr_t const *da, fr_sbuff_t *in); +fr_slen_t fr_dict_enum_by_name_substr(fr_dict_enum_value_t **out, fr_dict_attr_t const *da, fr_sbuff_t *in); fr_slen_t fr_dict_enum_name_from_substr(fr_sbuff_t *out, fr_sbuff_parse_error_t *err, fr_sbuff_t *in, fr_sbuff_term_t const *tt); diff --git a/src/lib/util/dict_unknown.c b/src/lib/util/dict_unknown.c index 6756802a631..9ae9a0b1143 100644 --- a/src/lib/util/dict_unknown.c +++ b/src/lib/util/dict_unknown.c @@ -409,31 +409,28 @@ fr_dict_attr_t *fr_dict_unknown_afrom_fields(TALLOC_CTX *ctx, fr_dict_attr_t con * - The number of bytes parsed on success. * - <= 0 on failure. Negative offset indicates parse error position. */ -ssize_t fr_dict_unknown_afrom_oid_substr(TALLOC_CTX *ctx, - fr_dict_attr_err_t *err, fr_dict_attr_t **out, - fr_dict_attr_t const *parent, - fr_sbuff_t *in, fr_sbuff_term_t const *tt) +fr_slen_t fr_dict_unknown_afrom_oid_substr(TALLOC_CTX *ctx, + fr_dict_attr_err_t *err, fr_dict_attr_t **out, + fr_dict_attr_t const *parent, + fr_sbuff_t *in, fr_sbuff_term_t const *tt) { + fr_sbuff_t our_in = FR_SBUFF(in); fr_dict_attr_t const *our_parent; fr_dict_attr_t *n = NULL; fr_dict_attr_err_t our_err; fr_dict_attr_flags_t flags = { .is_unknown = true }; - fr_sbuff_marker_t start; - ssize_t slen; bool is_raw; *out = NULL; - fr_sbuff_marker(&start, in); - - is_raw = fr_sbuff_adv_past_str_literal(in, "raw"); + is_raw = fr_sbuff_adv_past_str_literal(&our_in, "raw"); /* * Resolve all the known bits first... */ - slen = fr_dict_attr_by_oid_substr(&our_err, &our_parent, parent, in, tt); + (void)fr_dict_attr_by_oid_substr(&our_err, &our_parent, parent, &our_in, tt); switch (our_err) { /* * Um this is awkward, we were asked to @@ -458,7 +455,7 @@ ssize_t fr_dict_unknown_afrom_oid_substr(TALLOC_CTX *ctx, if (err) *err = FR_DICT_ATTR_OK; } - return fr_sbuff_marker_release_behind(&start); + return fr_sbuff_set(in, &our_in); /* * This is what we want... Everything @@ -491,8 +488,7 @@ ssize_t fr_dict_unknown_afrom_oid_substr(TALLOC_CTX *ctx, */ default: if (err) *err = our_err; - fr_sbuff_marker_release(&start); - return slen; + FR_SBUFF_ERROR_RETURN(&our_in); } /* @@ -514,15 +510,15 @@ ssize_t fr_dict_unknown_afrom_oid_substr(TALLOC_CTX *ctx, * fr_dict_attr_by_oid_substr parsed *something* * we expected the next component to be a '.'. */ - if (fr_sbuff_behind(&start) > 0) { - if (!fr_sbuff_next_if_char(in, '.')) { /* this is likely a logic bug if the test fails ? */ - fr_strerror_printf("Missing OID component separator %s", fr_sbuff_current(in)); + if (fr_sbuff_ahead(&our_in) > 0) { + if (!fr_sbuff_next_if_char(&our_in, '.')) { /* this is likely a logic bug if the test fails ? */ + fr_strerror_printf("Missing OID component separator %.*s", (int)fr_sbuff_remaining(&our_in), fr_sbuff_current(&our_in)); error: if (err) *err = FR_DICT_ATTR_PARSE_ERROR; talloc_free(n); - return -fr_sbuff_marker_release_reset_behind(&start); + FR_SBUFF_ERROR_RETURN(&our_in); } - } else if (fr_sbuff_next_if_char(in, '.')) { + } else if (fr_sbuff_next_if_char(&our_in, '.')) { our_parent = fr_dict_root(fr_dict_by_da(parent)); /* From the root */ } @@ -533,7 +529,7 @@ ssize_t fr_dict_unknown_afrom_oid_substr(TALLOC_CTX *ctx, uint32_t num; fr_sbuff_parse_error_t sberr; - fr_sbuff_out(&sberr, &num, in); + fr_sbuff_out(&sberr, &num, &our_in); switch (sberr) { case FR_SBUFF_PARSE_OK: switch (our_parent->type) { @@ -545,7 +541,7 @@ ssize_t fr_dict_unknown_afrom_oid_substr(TALLOC_CTX *ctx, { fr_dict_attr_t *ni; - if (fr_sbuff_next_if_char(in, '.')) { + if (fr_sbuff_next_if_char(&our_in, '.')) { ni = fr_dict_unknown_vendor_afrom_num(n, our_parent, num); if (!ni) goto error; our_parent = ni; @@ -564,7 +560,7 @@ ssize_t fr_dict_unknown_afrom_oid_substr(TALLOC_CTX *ctx, { fr_dict_attr_t *ni; - if (fr_sbuff_next_if_char(in, '.')) { + if (fr_sbuff_next_if_char(&our_in, '.')) { ni = fr_dict_unknown_tlv_afrom_num(n, our_parent, num); if (!ni) goto error; our_parent = ni; @@ -578,7 +574,7 @@ ssize_t fr_dict_unknown_afrom_oid_substr(TALLOC_CTX *ctx, * Leaf type with more components * is an error. */ - if (fr_sbuff_is_char(in, '.')) { + if (fr_sbuff_is_char(&our_in, '.')) { fr_strerror_printf("Interior OID component cannot proceed a %s type", fr_type_to_str(our_parent->type)); goto error; @@ -594,8 +590,8 @@ ssize_t fr_dict_unknown_afrom_oid_substr(TALLOC_CTX *ctx, { fr_sbuff_marker_t c_start; - fr_sbuff_marker(&c_start, in); - fr_sbuff_adv_past_allowed(in, FR_DICT_ATTR_MAX_NAME_LEN, fr_dict_attr_allowed_chars, NULL); + fr_sbuff_marker(&c_start, &our_in); + fr_sbuff_adv_past_allowed(&our_in, FR_DICT_ATTR_MAX_NAME_LEN, fr_dict_attr_allowed_chars, NULL); fr_strerror_printf("Unknown attribute \"%.*s\" for parent \"%s\"", (int)fr_sbuff_behind(&c_start), fr_sbuff_current(&c_start), our_parent->name); goto error; @@ -608,7 +604,7 @@ ssize_t fr_dict_unknown_afrom_oid_substr(TALLOC_CTX *ctx, *out = n; - return fr_sbuff_marker_release_behind(&start); + return fr_sbuff_set(in, &our_in); } /** Fixup the parent of an unknown attribute using an equivalent known attribute diff --git a/src/lib/util/dict_util.c b/src/lib/util/dict_util.c index f98559cc930..195726ecfca 100644 --- a/src/lib/util/dict_util.c +++ b/src/lib/util/dict_util.c @@ -22,12 +22,16 @@ */ RCSID("$Id$") +#define _DICT_PRIVATE 1 + +#include #include +#include #include #include #include +#include #include -#include #ifdef HAVE_SYS_STAT_H # include @@ -1801,13 +1805,13 @@ ssize_t fr_dict_attr_by_oid_legacy(fr_dict_t const *dict, fr_dict_attr_t const * * @param[in] tt Terminal strings. * @return * - >0 the number of bytes consumed. - * - <= 0 Parse error occurred here. + * - <0 Parse error occurred here. */ -ssize_t fr_dict_oid_component(fr_dict_attr_err_t *err, - fr_dict_attr_t const **out, fr_dict_attr_t const *parent, - fr_sbuff_t *in, fr_sbuff_term_t const *tt) +fr_slen_t fr_dict_oid_component(fr_dict_attr_err_t *err, + fr_dict_attr_t const **out, fr_dict_attr_t const *parent, + fr_sbuff_t *in, fr_sbuff_term_t const *tt) { - fr_sbuff_marker_t start; + fr_sbuff_t our_in = FR_SBUFF(in); uint32_t num = 0; fr_sbuff_parse_error_t sberr; fr_dict_attr_t const *child; @@ -1816,8 +1820,6 @@ ssize_t fr_dict_oid_component(fr_dict_attr_err_t *err, *out = NULL; - fr_sbuff_marker(&start, in); - switch (parent->type) { case FR_TYPE_STRUCTURAL: break; @@ -1828,20 +1830,20 @@ ssize_t fr_dict_oid_component(fr_dict_attr_err_t *err, "Error at OID \"%.*s\"", parent->name, fr_type_to_str(parent->type), - (int)fr_sbuff_remaining(in), - fr_sbuff_current(in)); + (int)fr_sbuff_remaining(&our_in), + fr_sbuff_current(&our_in)); if (err) *err =FR_DICT_ATTR_NO_CHILDREN; - return -fr_sbuff_marker_release_behind(&start); + FR_SBUFF_ERROR_RETURN(&our_in); } - fr_sbuff_out(&sberr, &num, in); + fr_sbuff_out(&sberr, &num, &our_in); switch (sberr) { /* * Lookup by number */ case FR_SBUFF_PARSE_OK: - if (!fr_sbuff_is_char(in, '.') && !fr_sbuff_is_terminal(in, tt)) { - fr_sbuff_set(in, &start); /* Reset to the start */ + if (!fr_sbuff_is_char(&our_in, '.') && !fr_sbuff_is_terminal(&our_in, tt)) { + fr_sbuff_set_to_start(&our_in); goto oid_str; } @@ -1850,10 +1852,7 @@ ssize_t fr_dict_oid_component(fr_dict_attr_err_t *err, fr_strerror_printf("Failed resolving child %u in context %s", num, parent->name); if (err) *err = FR_DICT_ATTR_NOTFOUND; - fr_sbuff_set(in, &start); /* Reset to start of number */ - fr_sbuff_marker_release(&start); - - return 0; + FR_SBUFF_ERROR_RETURN(&our_in); } break; @@ -1864,17 +1863,14 @@ ssize_t fr_dict_oid_component(fr_dict_attr_err_t *err, case FR_SBUFF_PARSE_ERROR_TRAILING: { fr_dict_attr_err_t our_err; - ssize_t slen; - oid_str: - slen = fr_dict_attr_by_name_substr(&our_err, &child, parent, in, tt); - if (our_err != FR_DICT_ATTR_OK) { + if (fr_dict_attr_by_name_substr(&our_err, &child, parent, &our_in, tt) < 0) { fr_strerror_printf("Failed resolving \"%.*s\" in context %s", - (int)fr_sbuff_remaining(in), - fr_sbuff_current(in), + (int)fr_sbuff_remaining(&our_in), + fr_sbuff_current(&our_in), parent->name); if (err) *err = our_err; - return slen - fr_sbuff_marker_release_behind(&start); + FR_SBUFF_ERROR_RETURN(&our_in); } } break; @@ -1882,77 +1878,70 @@ ssize_t fr_dict_oid_component(fr_dict_attr_err_t *err, default: fr_strerror_printf("Invalid OID component (%s) \"%.*s\"", fr_table_str_by_value(sbuff_parse_error_table, sberr, ""), - (int)fr_sbuff_remaining(in), fr_sbuff_current(in)); + (int)fr_sbuff_remaining(&our_in), fr_sbuff_current(&our_in)); if (err) *err = FR_DICT_ATTR_PARSE_ERROR; - return -fr_sbuff_marker_release_behind(&start); + FR_SBUFF_ERROR_RETURN(&our_in); } child = dict_attr_alias(err, child); - if (unlikely(!child)) return 0; + if (unlikely(!child)) FR_SBUFF_ERROR_RETURN(&our_in); *out = child; - return fr_sbuff_marker_release_behind(&start); + return fr_sbuff_set(in, &our_in); } /** Resolve an attribute using an OID string * * @note Will leave the sbuff pointing at the component the error occurred at * so that the caller can attempt to process the component in another way. + * An err pointer should be provided in order to determine if an error + * ocurred. * * @param[out] err The parsing error that occurred. * @param[out] out The deepest attribute we resolved. * @param[in] parent Where to resolve relative attributes from. * @param[in] in string to parse. * @param[in] tt Terminal strings. - * @return - * - >0 the number of bytes consumed. - * - <= 0 Parse error occurred here. + * @return The number of bytes of name consumed. */ -ssize_t fr_dict_attr_by_oid_substr(fr_dict_attr_err_t *err, - fr_dict_attr_t const **out, fr_dict_attr_t const *parent, - fr_sbuff_t *in, fr_sbuff_term_t const *tt) +fr_slen_t fr_dict_attr_by_oid_substr(fr_dict_attr_err_t *err, + fr_dict_attr_t const **out, fr_dict_attr_t const *parent, + fr_sbuff_t *in, fr_sbuff_term_t const *tt) { - fr_sbuff_marker_t start, c_s; + fr_sbuff_t our_in = FR_SBUFF(in); + fr_sbuff_marker_t m_c; fr_dict_attr_t const *our_parent = parent; - fr_sbuff_marker(&start, in); - fr_sbuff_marker(&c_s, in); + fr_sbuff_marker(&m_c, &our_in); /* * If the OID doesn't begin with '.' we * resolve it from the root. */ - #if 0 - if (!fr_sbuff_next_if_char(in, '.')) our_parent = fr_dict_root(fr_dict_by_da(parent)); + if (!fr_sbuff_next_if_char(&our_in, '.')) our_parent = fr_dict_root(fr_dict_by_da(parent)); #else - (void) fr_sbuff_next_if_char(in, '.'); + (void) fr_sbuff_next_if_char(&our_in, '.'); #endif *out = NULL; for (;;) { - ssize_t slen; fr_dict_attr_t const *child; - slen = fr_dict_oid_component(err, &child, our_parent, in, tt); - if ((slen <= 0) || !child) { - ssize_t ret = slen - fr_sbuff_behind(&start); - - fr_sbuff_set(in, &c_s); - fr_sbuff_marker_release(&start); - - return ret; + if ((fr_dict_oid_component(err, &child, our_parent, &our_in, tt) < 0) || !child) { + fr_sbuff_set(&our_in, &m_c); /* Reset to the start of the last component */ + break; /* Resolved as much as we can */ } our_parent = child; *out = child; - fr_sbuff_set(&c_s, in); - if (!fr_sbuff_next_if_char(in, '.')) break; + fr_sbuff_set(&m_c, &our_in); + if (!fr_sbuff_next_if_char(&our_in, '.')) break; } - return fr_sbuff_marker_release_behind(&start); + return fr_sbuff_set(in, &our_in); } /** Resolve an attribute using an OID string @@ -1969,7 +1958,8 @@ fr_dict_attr_t const *fr_dict_attr_by_oid(fr_dict_attr_err_t *err, fr_dict_attr_ fr_sbuff_t sbuff = FR_SBUFF_IN(oid, strlen(oid)); fr_dict_attr_t const *da; - if (fr_dict_attr_by_oid_substr(err, &da, parent, &sbuff, NULL) <= 0) return NULL; + fr_dict_attr_by_oid_substr(err, &da, parent, &sbuff, NULL); + if (err != FR_DICT_ATTR_OK) return NULL; return da; } @@ -1996,41 +1986,39 @@ dl_t *fr_dict_dl(fr_dict_t const *dict) return dict->dl; } -ssize_t dict_by_protocol_substr(fr_dict_attr_err_t *err, - fr_dict_t **out, fr_sbuff_t *name, fr_dict_t const *dict_def) +fr_slen_t dict_by_protocol_substr(fr_dict_attr_err_t *err, + fr_dict_t **out, fr_sbuff_t *name, fr_dict_t const *dict_def) { fr_dict_attr_t root; + fr_sbuff_t our_name = FR_SBUFF(name); fr_dict_t *dict; - size_t len; + fr_slen_t slen; char buffer[FR_DICT_ATTR_MAX_NAME_LEN + 1 + 1]; /* +1 \0 +1 for "too long" */ - fr_sbuff_t our_name; if (!dict_gctx || !name || !out) { if (err) *err = FR_DICT_ATTR_EINVAL; - return 0; + FR_SBUFF_ERROR_RETURN(&our_name); } - our_name = FR_SBUFF(name); - memset(&root, 0, sizeof(root)); /* * Advance p until we get something that's not part of * the dictionary attribute name. */ - len = fr_sbuff_out_bstrncpy_allowed(&FR_SBUFF_OUT(buffer, sizeof(buffer)), - &our_name, SIZE_MAX, - fr_dict_attr_allowed_chars); - if (len == 0) { + slen = fr_sbuff_out_bstrncpy_allowed(&FR_SBUFF_OUT(buffer, sizeof(buffer)), + &our_name, SIZE_MAX, + fr_dict_attr_allowed_chars); + if (slen == 0) { fr_strerror_const("Zero length attribute name"); if (err) *err = FR_DICT_ATTR_PARSE_ERROR; - return 0; + FR_SBUFF_ERROR_RETURN(&our_name); } - if (len > FR_DICT_ATTR_MAX_NAME_LEN) { + if (slen > FR_DICT_ATTR_MAX_NAME_LEN) { fr_strerror_const("Attribute name too long"); if (err) *err = FR_DICT_ATTR_PARSE_ERROR; - return -(FR_DICT_ATTR_MAX_NAME_LEN); + FR_SBUFF_ERROR_RETURN(&our_name); } /* @@ -2054,7 +2042,8 @@ ssize_t dict_by_protocol_substr(fr_dict_attr_err_t *err, if (strcasecmp(root.name, "internal") != 0) { fr_strerror_printf("Unknown protocol '%s'", root.name); memcpy(out, &dict_def, sizeof(*out)); - return 0; + fr_sbuff_set_to_start(&our_name); + FR_SBUFF_ERROR_RETURN(&our_name); } dict = dict_gctx->internal; @@ -2062,7 +2051,7 @@ ssize_t dict_by_protocol_substr(fr_dict_attr_err_t *err, *out = dict; - return (size_t)fr_sbuff_set(name, &our_name); + return fr_sbuff_set(name, &our_name); } /** Look up a protocol name embedded in another string @@ -2074,18 +2063,12 @@ ssize_t dict_by_protocol_substr(fr_dict_attr_err_t *err, * @param[in] dict_def The dictionary to return if no dictionary qualifier was found. * @return * - 0 and *out != NULL. Couldn't find a dictionary qualifier, so returned dict_def. - * - <= 0 on error and (*out == NULL) (offset as negative integer) + * - < 0 on error and (*out == NULL) (offset as negative integer) * - > 0 on success (number of bytes parsed). */ -ssize_t fr_dict_by_protocol_substr(fr_dict_attr_err_t *err, fr_dict_t const **out, fr_sbuff_t *name, fr_dict_t const *dict_def) +fr_slen_t fr_dict_by_protocol_substr(fr_dict_attr_err_t *err, fr_dict_t const **out, fr_sbuff_t *name, fr_dict_t const *dict_def) { - ssize_t slen; - fr_dict_t *dict = NULL; - - slen = dict_by_protocol_substr(err, &dict, name, dict_def); - *out = dict; - - return slen; + return dict_by_protocol_substr(err, UNCONST(fr_dict_t **, out), name, dict_def); } /** Internal version of #fr_dict_by_protocol_name @@ -2305,12 +2288,12 @@ fr_dict_attr_t const *fr_dict_vendor_da_by_num(fr_dict_attr_t const *vendor_root * @param[in] tt Terminal sequences to use to determine the portion * of in to search. * @return - * - <= 0 on failure. + * - < 0 on failure. * - The number of bytes of name consumed on success. */ -typedef ssize_t (*dict_attr_resolve_func_t)(fr_dict_attr_err_t *err, - fr_dict_attr_t const **out, fr_dict_attr_t const *parent, - fr_sbuff_t *in, fr_sbuff_term_t const *tt); +typedef fr_slen_t (*dict_attr_resolve_func_t)(fr_dict_attr_err_t *err, + fr_dict_attr_t const **out, fr_dict_attr_t const *parent, + fr_sbuff_t *in, fr_sbuff_term_t const *tt); /** Internal function for searching for attributes in multiple dictionaries * @@ -2328,17 +2311,15 @@ typedef ssize_t (*dict_attr_resolve_func_t)(fr_dict_attr_err_t *err, * - >0 on success. */ static inline CC_HINT(always_inline) -ssize_t dict_attr_search(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, - fr_dict_t const *dict_def, - fr_sbuff_t *in, fr_sbuff_term_t const *tt, - bool internal, bool foreign, - dict_attr_resolve_func_t func) +fr_slen_t dict_attr_search(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, + fr_dict_t const *dict_def, + fr_sbuff_t *in, fr_sbuff_term_t const *tt, + bool internal, bool foreign, + dict_attr_resolve_func_t func) { fr_dict_attr_err_t our_err = FR_DICT_ATTR_OK; fr_hash_iter_t iter; fr_dict_t *dict = NULL; - - ssize_t slen = 0; fr_sbuff_t our_in = FR_SBUFF(in); if (internal && !dict_gctx->internal) internal = false; @@ -2355,7 +2336,7 @@ ssize_t dict_attr_search(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, * dict_def search in the specified dictionary */ if (dict_def) { - slen = func(&our_err, out, fr_dict_root(dict_def), &our_in, tt); + (void)func(&our_err, out, fr_dict_root(dict_def), &our_in, tt); switch (our_err) { case FR_DICT_ATTR_OK: return fr_sbuff_set(in, &our_in); @@ -2373,7 +2354,7 @@ ssize_t dict_attr_search(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, * Next in the internal dictionary */ if (internal) { - slen = func(&our_err, out, fr_dict_root(dict_gctx->internal), &our_in, tt); + (void)func(&our_err, out, fr_dict_root(dict_gctx->internal), &our_in, tt); switch (our_err) { case FR_DICT_ATTR_OK: return fr_sbuff_set(in, &our_in); @@ -2468,7 +2449,7 @@ done: if (err) *err = our_err; *out = NULL; - FR_SBUFF_ERROR_RETURN_ADJ(&our_in, slen); + FR_SBUFF_ERROR_RETURN(&our_in); } /** Internal function for searching for attributes in multiple dictionaries @@ -2477,16 +2458,16 @@ done: * the attribute identifier. */ static inline CC_HINT(always_inline) -ssize_t dict_attr_search_qualified(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, - fr_dict_t const *dict_def, - fr_sbuff_t *in, fr_sbuff_term_t const *tt, - bool internal, bool foreign, - dict_attr_resolve_func_t func) +fr_slen_t dict_attr_search_qualified(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, + fr_dict_t const *dict_def, + fr_sbuff_t *in, fr_sbuff_term_t const *tt, + bool internal, bool foreign, + dict_attr_resolve_func_t func) { fr_sbuff_t our_in = FR_SBUFF(in); fr_dict_attr_err_t our_err; fr_dict_t *initial; - ssize_t slen; + fr_slen_t slen; /* * Check for dictionary prefix @@ -2496,8 +2477,7 @@ ssize_t dict_attr_search_qualified(fr_dict_attr_err_t *err, fr_dict_attr_t const error: if (err) *err = our_err; *out = NULL; - - FR_SBUFF_ERROR_RETURN_ADJ(&our_in, slen); + FR_SBUFF_ERROR_RETURN(&our_in); } /* @@ -2509,15 +2489,13 @@ ssize_t dict_attr_search_qualified(fr_dict_attr_err_t *err, fr_dict_attr_t const */ if (!fr_sbuff_next_if_char(&our_in, '.')) { if (err) *err = FR_DICT_ATTR_PARSE_ERROR; - return 0; + FR_SBUFF_ERROR_RETURN(&our_in); } internal = foreign = false; } - slen = dict_attr_search(&our_err, out, initial, &our_in, tt, internal, foreign, func); - if (our_err != FR_DICT_ATTR_OK) goto error; - + if (dict_attr_search(&our_err, out, initial, &our_in, tt, internal, foreign, func) < 0) goto error; if (err) *err = FR_DICT_ATTR_OK; return fr_sbuff_set(in, &our_in); @@ -2543,13 +2521,13 @@ ssize_t dict_attr_search_qualified(fr_dict_attr_err_t *err, fr_dict_attr_t const * @param[in] internal If true, fallback to the internal dictionary. * @param[in] foreign If true, fallback to foreign dictionaries. * @return - * - <= 0 on failure. + * - < 0 on failure. * - The number of bytes of name consumed on success. */ -ssize_t fr_dict_attr_search_by_qualified_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, - fr_dict_t const *dict_def, - fr_sbuff_t *name, fr_sbuff_term_t const *tt, - bool internal, bool foreign) +fr_slen_t fr_dict_attr_search_by_qualified_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, + fr_dict_t const *dict_def, + fr_sbuff_t *name, fr_sbuff_term_t const *tt, + bool internal, bool foreign) { return dict_attr_search_qualified(err, out, dict_def, name, tt, internal, foreign, fr_dict_attr_by_name_substr); @@ -2572,13 +2550,13 @@ ssize_t fr_dict_attr_search_by_qualified_name_substr(fr_dict_attr_err_t *err, fr * @param[in] internal If true, fallback to the internal dictionary. * @param[in] foreign If true, fallback to foreign dictionaries. * @return - * - <= 0 on failure. + * - < 0 on failure. * - The number of bytes of name consumed on success. */ -ssize_t fr_dict_attr_search_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, - fr_dict_t const *dict_def, - fr_sbuff_t *name, fr_sbuff_term_t const *tt, - bool internal, bool foreign) +fr_slen_t fr_dict_attr_search_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, + fr_dict_t const *dict_def, + fr_sbuff_t *name, fr_sbuff_term_t const *tt, + bool internal, bool foreign) { return dict_attr_search_qualified(err, out, dict_def, name, tt, internal, foreign, fr_dict_attr_by_name_substr); @@ -2592,6 +2570,8 @@ ssize_t fr_dict_attr_search_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr * @note If calling this function from the server any list or request qualifiers * should be stripped first. * + * @note err should be checked to determine if a parse error ocurred. + * * @param[out] err Why parsing failed. May be NULL. * @see fr_dict_attr_err_t * @param[out] out Dictionary found attribute. @@ -2600,14 +2580,12 @@ ssize_t fr_dict_attr_search_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr * @param[in] tt Terminal strings. * @param[in] internal If true, fallback to the internal dictionary. * @param[in] foreign If true, fallback to foreign dictionaries. - * @return - * - <= 0 on failure. - * - The number of bytes of name consumed on success. + * @return The number of bytes of name consumed. */ -ssize_t fr_dict_attr_search_by_qualified_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, - fr_dict_t const *dict_def, - fr_sbuff_t *in, fr_sbuff_term_t const *tt, - bool internal, bool foreign) +fr_slen_t fr_dict_attr_search_by_qualified_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, + fr_dict_t const *dict_def, + fr_sbuff_t *in, fr_sbuff_term_t const *tt, + bool internal, bool foreign) { return dict_attr_search_qualified(err, out, dict_def, in, tt, internal, foreign, fr_dict_attr_by_oid_substr); @@ -2621,6 +2599,8 @@ ssize_t fr_dict_attr_search_by_qualified_oid_substr(fr_dict_attr_err_t *err, fr_ * @note If calling this function from the server any list or request qualifiers * should be stripped first. * + * @note err should be checked to determine if a parse error ocurred. + * * @param[out] err Why parsing failed. May be NULL. * @see fr_dict_attr_err_t * @param[out] out Dictionary found attribute. @@ -2629,14 +2609,12 @@ ssize_t fr_dict_attr_search_by_qualified_oid_substr(fr_dict_attr_err_t *err, fr_ * @param[in] tt Terminal strings. * @param[in] internal If true, fallback to the internal dictionary. * @param[in] foreign If true, fallback to foreign dictionaries. - * @return - * - <= 0 on failure. - * - The number of bytes of name consumed on success. + * @return The number of bytes of name consumed. */ -ssize_t fr_dict_attr_search_by_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, - fr_dict_t const *dict_def, - fr_sbuff_t *in, fr_sbuff_term_t const *tt, - bool internal, bool foreign) +fr_slen_t fr_dict_attr_search_by_oid_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, + fr_dict_t const *dict_def, + fr_sbuff_t *in, fr_sbuff_term_t const *tt, + bool internal, bool foreign) { return dict_attr_search_qualified(err, out, dict_def, in, tt, internal, foreign, fr_dict_attr_by_oid_substr); @@ -2659,12 +2637,15 @@ fr_dict_attr_t const *fr_dict_attr_search_by_qualified_oid(fr_dict_attr_err_t *e ssize_t slen; fr_sbuff_t our_name; fr_dict_attr_t const *da; + fr_dict_attr_err_t our_err; fr_sbuff_init_in(&our_name, name, strlen(name)); - slen = fr_dict_attr_search_by_qualified_oid_substr(err, &da, dict_def, &our_name, NULL, internal, foreign); - if (slen <= 0) return NULL; - + slen = fr_dict_attr_search_by_qualified_oid_substr(&our_err, &da, dict_def, &our_name, NULL, internal, foreign); + if (our_err != FR_DICT_ATTR_OK) { + if (err) *err = our_err; + return NULL; + } if ((size_t)slen != fr_sbuff_len(&our_name)) { fr_strerror_printf("Trailing garbage after attr string \"%s\"", name); if (err) *err = FR_DICT_ATTR_PARSE_ERROR; @@ -2700,8 +2681,8 @@ fr_dict_attr_t const *fr_dict_attr_search_by_qualified_oid(fr_dict_attr_err_t *e * - <= 0 on failure. * - The number of bytes of name consumed on success. */ -ssize_t fr_dict_attr_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, - fr_dict_attr_t const *parent, fr_sbuff_t *name, UNUSED fr_sbuff_term_t const *tt) +fr_slen_t fr_dict_attr_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t const **out, + fr_dict_attr_t const *parent, fr_sbuff_t *name, UNUSED fr_sbuff_term_t const *tt) { fr_dict_attr_t const *da; size_t len; @@ -2717,12 +2698,12 @@ ssize_t fr_dict_attr_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t cons if (len == 0) { fr_strerror_const("Zero length attribute name"); if (err) *err = FR_DICT_ATTR_PARSE_ERROR; - return 0; + FR_SBUFF_ERROR_RETURN(&our_name); } if (len > FR_DICT_ATTR_MAX_NAME_LEN) { fr_strerror_const("Attribute name too long"); if (err) *err = FR_DICT_ATTR_PARSE_ERROR; - return -(FR_DICT_ATTR_MAX_NAME_LEN); + FR_SBUFF_ERROR_RETURN(&our_name); } ref = fr_dict_attr_ref(parent); @@ -2732,18 +2713,20 @@ ssize_t fr_dict_attr_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t cons if (!namespace) { fr_strerror_printf("Attribute '%s' does not contain a namespace", parent->name); if (err) *err = FR_DICT_ATTR_NO_CHILDREN; - return -1; + fr_sbuff_set_to_start(&our_name); + FR_SBUFF_ERROR_RETURN(&our_name); } da = fr_hash_table_find(namespace, &(fr_dict_attr_t){ .name = buffer }); if (!da) { if (err) *err = FR_DICT_ATTR_NOTFOUND; fr_strerror_printf("Attribute '%s' not found in namespace '%s'", buffer, parent->name); - return 0; + fr_sbuff_set_to_start(&our_name); + FR_SBUFF_ERROR_RETURN(&our_name); } da = dict_attr_alias(err, da); - if (unlikely(!da)) return 0; + if (unlikely(!da)) FR_SBUFF_ERROR_RETURN(&our_name); *out = da; if (err) *err = FR_DICT_ATTR_OK; @@ -2948,7 +2931,7 @@ fr_dict_enum_value_t *fr_dict_enum_by_name(fr_dict_attr_t const *da, char const /* * Get a value by its name, keyed off of an attribute, from an sbuff */ -ssize_t fr_dict_enum_by_name_substr(fr_dict_enum_value_t **out, fr_dict_attr_t const *da, fr_sbuff_t *in) +fr_slen_t fr_dict_enum_by_name_substr(fr_dict_enum_value_t **out, fr_dict_attr_t const *da, fr_sbuff_t *in) { fr_dict_attr_ext_enumv_t *ext; fr_sbuff_t our_in = FR_SBUFF(in); @@ -3057,12 +3040,13 @@ fr_slen_t fr_dict_enum_name_from_substr(fr_sbuff_t *out, fr_sbuff_parse_error_t if (fr_sbuff_used(&our_in) == 0) { fr_strerror_const("VALUE name is empty"); if (err) *err = FR_SBUFF_PARSE_ERROR_NOT_FOUND; - return -1; + return fr_sbuff_error(&our_in); } fr_strerror_const("VALUE name must contain at least one alpha character"); if (err) *err = FR_SBUFF_PARSE_ERROR_FORMAT; - return -1; + fr_sbuff_set_to_start(&our_in); /* Marker should be at the start of the enum */ + return fr_sbuff_error(&our_in); } /* diff --git a/src/lib/util/pair_legacy.c b/src/lib/util/pair_legacy.c index e6417b73034..c69c7529437 100644 --- a/src/lib/util/pair_legacy.c +++ b/src/lib/util/pair_legacy.c @@ -20,6 +20,7 @@ * * @copyright 2000,2006,2015 The FreeRADIUS server project */ +#include "lib/util/dict.h" RCSID("$Id$") #include @@ -133,6 +134,7 @@ static ssize_t fr_pair_list_afrom_substr(TALLOC_CTX *ctx, fr_dict_attr_t const * if (strncmp(p, "raw.", 4) == 0) goto do_unknown; if (*p == '.') { + fr_dict_attr_err_t err; p++; if (!*relative_vp) { @@ -140,27 +142,27 @@ static ssize_t fr_pair_list_afrom_substr(TALLOC_CTX *ctx, fr_dict_attr_t const * goto error; } - slen = fr_dict_attr_by_oid_substr(NULL, &da, (*relative_vp)->da, - &FR_SBUFF_IN(p, (end - p)), &bareword_terminals); - if (slen <= 0) goto error; + slen = fr_dict_attr_by_oid_substr(&err, &da, (*relative_vp)->da, &FR_SBUFF_IN(p, (end - p)), &bareword_terminals); + if (err != FR_DICT_ATTR_OK) goto error; my_list = &(*relative_vp)->vp_group; my_ctx = *relative_vp; } else { + fr_dict_attr_err_t err; + /* * Parse the name. */ - slen = fr_dict_attr_by_oid_substr(NULL, &da, parent, - &FR_SBUFF_IN(p, (end - p)), &bareword_terminals); - if ((slen <= 0) && internal) { - slen = fr_dict_attr_by_oid_substr(NULL, &da, internal, - &FR_SBUFF_IN(p, (end - p)), &bareword_terminals); + slen = fr_dict_attr_by_oid_substr(&err, &da, parent, &FR_SBUFF_IN(p, (end - p)), &bareword_terminals); + if ((err != FR_DICT_ATTR_OK) && internal) { + slen = fr_dict_attr_by_oid_substr(&err, &da, internal, + &FR_SBUFF_IN(p, (end - p)), &bareword_terminals); } - if (slen <= 0) { + if (err != FR_DICT_ATTR_OK) { do_unknown: slen = fr_dict_unknown_afrom_oid_substr(ctx, NULL, &da_unknown, parent, &FR_SBUFF_IN(p, (end - p)), &bareword_terminals); - if (slen <= 0) { + if (slen < 0) { p += -slen; error: diff --git a/src/lib/util/sbuff.h b/src/lib/util/sbuff.h index 245c766addc..199dbbcc44a 100644 --- a/src/lib/util/sbuff.h +++ b/src/lib/util/sbuff.h @@ -907,12 +907,24 @@ static inline fr_sbuff_t *fr_sbuff_init_talloc(TALLOC_CTX *ctx, */ static inline fr_slen_t _fr_sbuff_error(fr_sbuff_t *sbuff, char const *err) { - fr_sbuff_t *parent = sbuff->parent; + fr_sbuff_t *parent = sbuff->parent; + fr_slen_t slen; if (sbuff->err) err = sbuff->err; if (parent) parent->err = err; - return -((err - fr_sbuff_start(sbuff)) + 1); + slen = -((err - fr_sbuff_start(sbuff)) + 1); + +#ifdef __clang_analyzer__ + /* + * Convince clang that the return value + * is always negative. It never can be + * else the sbuff code is very broken. + */ + if (slen >= 0) return -1; +#endif + + return slen; } /** Return the current position as an error marker @@ -971,11 +983,6 @@ static inline fr_slen_t _fr_sbuff_error(fr_sbuff_t *sbuff, char const *err) */ #define FR_SBUFF_ERROR_RETURN(_sbuff_or_marker) return fr_sbuff_error(_sbuff_or_marker) -/** Return the current adjusted position in the sbuff as a negative offset - * - */ -#define FR_SBUFF_ERROR_RETURN_ADJ(_sbuff, _slen) return -((fr_sbuff_used(_sbuff) + ((_slen) * -1))) - /** Check if _len bytes are available in the sbuff, and if not return the number of bytes we'd need * */ diff --git a/src/tests/unit/condition/base.txt b/src/tests/unit/condition/base.txt index 354bee61aad..da42eb8c9bf 100644 --- a/src/tests/unit/condition/base.txt +++ b/src/tests/unit/condition/base.txt @@ -28,7 +28,7 @@ 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 17: Unexpected text after condition +match ERROR offset 18: Unexpected text after condition # escapes in names are illegal condition (ok\ foo || handled) @@ -38,13 +38,13 @@ 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 4: Invalid operator +match ERROR offset 5: Invalid operator condition (ok !x handled) -match ERROR offset 4: Invalid operator +match ERROR offset 5: Invalid operator condition (ok =x handled) -match ERROR offset 4: Invalid operator +match ERROR offset 5: Invalid operator # # Re-enable when we have proper bareword xlat tokenization @@ -71,7 +71,7 @@ condition !(ok) match !ok condition !!ok -match ERROR offset 1: Double negation is invalid +match ERROR offset 2: Double negation is invalid condition !(!ok) match ok @@ -96,7 +96,7 @@ condition (!(&User-Name == &User-Password) || (&Filter-Id == &Reply-Message)) match !(&User-Name == &User-Password) || (&Filter-Id == &Reply-Message) condition ((a == b) || (c == d))) -match ERROR offset 22: Unexpected closing brace +match ERROR offset 23: Unexpected closing brace condition (handled && (&Packet-Type == Access-Challenge)) match handled && (&Packet-Type == Access-Challenge) @@ -110,13 +110,13 @@ condition handled &&&Packet-Type == Access-Challenge match handled && &Packet-Type == Access-Challenge condition &reply == &request -match ERROR offset 0: Cannot use list references in condition +match ERROR offset 1: Cannot use list references in condition condition &reply == "hello" -match ERROR offset 0: Cannot use list references in condition +match ERROR offset 1: Cannot use list references in condition condition "hello" == &reply -match ERROR offset 11: Cannot use list references in condition +match ERROR offset 12: Cannot use list references in condition # @@ -132,7 +132,7 @@ condition !&User-Name != &User-Password match &User-Name == &User-Password condition ::1 -match ERROR offset 0: Invalid cast from ipv6addr to bool. Unsupported +match ERROR offset 1: Invalid cast from ipv6addr to bool. Unsupported condition &Filter-Id == &Framed-IP-Address match &Filter-Id == &Framed-IP-Address @@ -158,23 +158,23 @@ match &Framed-IP-Address > 127.0.0.1 # =* and !* are only for attrs / lists condition "foo" !* bar -match ERROR offset 6: Invalid operator !* +match ERROR offset 7: Invalid operator !* condition "foo" =* bar -match ERROR offset 6: Invalid operator =* +match ERROR offset 7: Invalid operator =* # existence checks don't need the RHS condition &User-Name =* bar -match ERROR offset 11: Invalid operator =* +match ERROR offset 12: Invalid operator =* condition &User-Name !* bar -match ERROR offset 11: Invalid operator !* +match ERROR offset 12: Invalid operator !* condition !&User-Name =* bar -match ERROR offset 12: Invalid operator =* +match ERROR offset 13: Invalid operator =* condition !&User-Name !* bar -match ERROR offset 12: Invalid operator !* +match ERROR offset 13: Invalid operator !* # redundant casts get squashed condition &Framed-IP-Address == 127.0.0.1 @@ -222,7 +222,7 @@ condition X == 1 match ERROR offset 10: Failed parsing string as type 'uint32' condition &NAS-Port == X -match ERROR offset 13: Failed parsing string as type 'uint32' +match ERROR offset 14: Failed parsing string as type 'uint32' # # The RHS is a static string, so this gets mashed to a literal, @@ -337,7 +337,7 @@ condition 127.0.0.1/32 == 127.0.0.1 match true condition (/foo/) -match ERROR offset 1: Unexpected regular expression +match ERROR offset 2: Unexpected regular expression # # Tests for (FOO). @@ -370,7 +370,7 @@ condition ('a') match true condition (a) -match ERROR offset 1: Expected a module return code +match ERROR offset 2: Expected a module return code # # Module return codes are OK diff --git a/src/tests/unit/condition/regex.txt b/src/tests/unit/condition/regex.txt index fdc04845844..24c8bbc794a 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 7: Expected regular expression +match ERROR offset 8: Expected regular expression condition (ok == /foo/) -match ERROR offset 7: Unexpected regular expression +match ERROR offset 8: Unexpected regular expression # # bare words are cast to strings @@ -69,7 +69,7 @@ match &Tmp-Integer-0 =~ /%{Tmp-Integer-0}/ # Cannot add a bad cast # condition &Tmp-String-0 =~ /foo/ -match ERROR offset 9: Casts cannot be used with regular expressions +match ERROR offset 10: Casts cannot be used with regular expressions condition &Tmp-String-0 =~ /foo/ match ERROR offset 28: Casts cannot be used with regular expressions @@ -79,10 +79,10 @@ xlat %{1} match %{1} xlat %{33} -match ERROR offset 2: Invalid regex reference. Must be in range 0-32 +match ERROR offset 3: Invalid regex reference. Must be in range 0-32 condition &User-Name == /foo/ -match ERROR offset 14: Unexpected regular expression +match ERROR offset 15: Unexpected regular expression count match 43 diff --git a/src/tests/unit/xlat/base.txt b/src/tests/unit/xlat/base.txt index d968aac0ded..1b8bcd0980d 100644 --- a/src/tests/unit/xlat/base.txt +++ b/src/tests/unit/xlat/base.txt @@ -61,16 +61,16 @@ xlat %{32} match %{32} xlat %{33} -match ERROR offset 2: Invalid regex reference. Must be in range 0-32 +match ERROR offset 3: Invalid regex reference. Must be in range 0-32 xlat %{3a} -match ERROR offset 2: Unexpected text after attribute reference +match ERROR offset 3: Unexpected text after attribute reference xlat %{-3} -match ERROR offset 2: Unresolved attributes not allowed in expansions here +match ERROR offset 3: Unresolved attributes not allowed in expansions here xlat %{3 -match ERROR offset 3: Missing closing brace +match ERROR offset 4: Missing closing brace # # Tests for xlat expansion @@ -136,10 +136,10 @@ xlat %(length:) match %(length:) xlat %(length: -match ERROR offset 9: Missing closing brace +match ERROR offset 10: Missing closing brace xlat %(length:1 + 2 -match ERROR offset 14: Missing closing brace +match ERROR offset 15: Missing closing brace xlat \"%t\tfoo\" match \"%t\tfoo\" @@ -156,10 +156,10 @@ match \"foo %{test:foo}\" # Alternations # xlat %{%{foo}:-%{bar}} -match ERROR offset 4: Unresolved attributes not allowed in expansions here +match ERROR offset 5: Unresolved attributes not allowed in expansions here xlat %{%{User-Name}:-%{bar}} -match ERROR offset 18: Unresolved attributes not allowed in expansions here +match ERROR offset 19: Unresolved attributes not allowed in expansions here xlat %{%{User-Name}:-bar} match %{%{User-Name}:-bar} @@ -186,57 +186,57 @@ xlat %{%{%{User-Name}:-foo}:-%{%{test:bar}:-%{User-Name}}} match %{%{%{User-Name}:-foo}:-%{%{test:bar}:-%{User-Name}}} xlat %{:-} -match ERROR offset 2: First item in alternation cannot be empty +match ERROR offset 3: First item in alternation cannot be empty xlat %{:-%{User-Name}} -match ERROR offset 2: First item in alternation cannot be empty +match ERROR offset 3: First item in alternation cannot be empty xlat %{%{}:-} -match ERROR offset 4: Empty expression is invalid +match ERROR offset 5: Empty expression is invalid xlat %{%{}:-foo} -match ERROR offset 4: Empty expression is invalid +match ERROR offset 5: Empty expression is invalid xlat %{%{User-Name}:- -match ERROR offset 16: Missing closing brace +match ERROR offset 17: Missing closing brace # Discuss - Not sure the offset/message is correct here, but not sure if we can determine the correct offset either xlat %{%{User-Name}:-foo -match ERROR offset 19: Missing closing brace +match ERROR offset 20: Missing closing brace xlat %{%{User-Name}:} -match ERROR offset 14: Expected ':-' after first expansion +match ERROR offset 15: Expected ':-' after first expansion xlat %{%{User-Name}} -match ERROR offset 14: Expected ':-' after first expansion +match ERROR offset 15: Expected ':-' after first expansion # # Empty and malformed expansions # xlat %{ -match ERROR offset 2: Missing closing brace +match ERROR offset 3: Missing closing brace xlat %{} -match ERROR offset 2: Empty expression is invalid +match ERROR offset 3: Empty expression is invalid xlat %{:} -match ERROR offset 2: Missing expansion function +match ERROR offset 3: Missing expansion function xlat %{:bar} -match ERROR offset 2: Missing expansion function +match ERROR offset 3: Missing expansion function xlat %{foo: bar} -match ERROR offset 2: Unresolved expansion functions are not allowed here +match ERROR offset 3: Unresolved expansion functions are not allowed here xlat %{[} -match ERROR offset 2: Missing attribute name +match ERROR offset 3: Missing attribute name xlat %{[baz} -match ERROR offset 2: Missing attribute name +match ERROR offset 3: Missing attribute name xlat %{ } -match ERROR offset 2: Invalid char ' ' in expression +match ERROR offset 3: Invalid char ' ' in expression xlat %{\t} match ERROR offset 3: Invalid attribute name @@ -245,27 +245,27 @@ xlat %{\n} match ERROR offset 3: Invalid attribute name xlat %{foo } -match ERROR offset 5: Invalid char ' ' in expression +match ERROR offset 6: Invalid char ' ' in expression xlat %{foo bar} -match ERROR offset 5: Invalid char ' ' in expression +match ERROR offset 6: Invalid char ' ' in expression xlat %{test: -match ERROR offset 7: Missing closing brace +match ERROR offset 8: Missing closing brace xlat %{test:%{User-Name -match ERROR offset 18: Missing closing brace +match ERROR offset 19: Missing closing brace # Discuss - Not sure the offset/message is correct here, but not sure if we can determine the correct offset either xlat %{test:%{User-Name} -match ERROR offset 19: Missing closing brace +match ERROR offset 20: Missing closing brace xlat %{myfirstxlat -match ERROR offset 13: Missing closing brace +match ERROR offset 14: Missing closing brace # Issue seen in the wild that caused an SEGV during pass2 xlat %{%{control.IP-Pool.Name}:%{reply.IP-Pool.Range} -match ERROR offset 25: Expected ':-' after first expansion +match ERROR offset 26: Expected ':-' after first expansion # # API to split xlat strings into argv-style arguments. @@ -294,7 +294,7 @@ match [0]{ /bin/sh }, [1]{ foo bar }, [2]{ %{User-Name} %{Filter-Id} } # and errors xlat_argv /bin/sh "foo bar" "%{User-Name} %{Filter-Id" -match ERROR offset 44: Missing closing brace +match ERROR offset 45: Missing closing brace # and text immediately after a variable expansion xlat_argv echo hello %{Tmp-String-0}:1234 world @@ -322,7 +322,7 @@ match %(rpad:&User-Name 5 x) # so the "offset 23" is wrong. It also doesn't say *which* string is wrong. We'll fix that later. # xlat %(rpad:&User-Name foo x) -match ERROR offset 23: Failed parsing argument 1 as type 'uint64' +match ERROR offset 24: Failed parsing argument 1 as type 'uint64' count match 187 diff --git a/src/tests/unit/xlat/cond_base.txt b/src/tests/unit/xlat/cond_base.txt index 87ff2021817..83c3a9b8b5d 100644 --- a/src/tests/unit/xlat/cond_base.txt +++ b/src/tests/unit/xlat/cond_base.txt @@ -43,7 +43,7 @@ xlat_purify (ok !x handled) match ERROR offset 5: Invalid operator xlat_purify (ok =x handled) -match ERROR offset 4: Invalid operator +match ERROR offset 5: Invalid operator # # Re-enable when we have proper bareword xlat tokenization @@ -73,7 +73,7 @@ match ERROR offset 4: Invalid operator #match !ok xlat_purify !!true -match ERROR offset 1: Double operator is invalid +match ERROR offset 2: Double operator is invalid #xlat_purify !(!ok) #match ok @@ -101,13 +101,13 @@ match (!(&User-Name == &User-Password) || (&Filter-Id == &Reply-Message)) # '!' is higher precedence that '==', so the '!' applies just to the User-Name # xlat_purify (!&User-Name == &User-Password || &Filter-Id == &Reply-Message) -match ERROR offset 1: Operator '!' is only applied to the left hand side of the '==' operation, add (..) to evaluate the operation first +match ERROR offset 2: Operator '!' is only applied to the left hand side of the '==' operation, add (..) to evaluate the operation first # # LHS is a boolean, which we then compare to a string # xlat_purify (!"foo" == "bar") -match ERROR offset 1: Operator '!' is only applied to the left hand side of the '==' operation, add (..) to evaluate the operation first +match ERROR offset 2: Operator '!' is only applied to the left hand side of the '==' operation, add (..) to evaluate the operation first xlat_purify ((!"foo") == "bar") match NULL @@ -139,13 +139,13 @@ xlat_purify 'handled' &&&Packet-Type == Access-Challenge match (&Packet-Type == Access-Challenge) xlat_purify &reply == &request -match ERROR offset 0: Cannot use list references in condition +match ERROR offset 1: Cannot use list references in condition xlat_purify &reply == "hello" -match ERROR offset 0: Cannot use list references in condition +match ERROR offset 1: Cannot use list references in condition xlat_purify "hello" == &reply -match ERROR offset 11: Cannot use list references in condition +match ERROR offset 12: Cannot use list references in condition # @@ -158,7 +158,7 @@ xlat_purify &User-Name != &User-Password match (&User-Name != &User-Password) xlat_purify !&User-Name != &User-Password -match ERROR offset 0: Operator '!' is only applied to the left hand side of the '!=' operation, add (..) to evaluate the operation first +match ERROR offset 1: Operator '!' is only applied to the left hand side of the '!=' operation, add (..) to evaluate the operation first # # We allow a cast for the existence check. Why not? @@ -254,7 +254,7 @@ match ERROR offset 10: Failed parsing string as type 'uint32' # string the RHS is. # xlat_purify &NAS-Port == X -match ERROR offset 0: Failed parsing string as type 'uint32' +match ERROR offset 1: Failed parsing string as type 'uint32' #match ERROR offset 13: Failed parsing string as type 'uint32' # @@ -378,7 +378,7 @@ xlat_purify 127.0.0.1/32 == 127.0.0.1 match true xlat_purify (/foo/) -match ERROR offset 1: Unexpected regular expression +match ERROR offset 2: Unexpected regular expression # # Tests for (FOO). @@ -757,7 +757,7 @@ xlat_purify (&User-Name == "bob") && (&User-Password == "bob") && handled match ((&User-Name == "bob") && (&User-Password == "bob") && %{rcode:'handled'}) xlat_purify handledx -match ERROR offset 0: Unexpected text - attribute names must prefixed with '&' +match ERROR offset 1: Unexpected text - attribute names must prefixed with '&' xlat_purify handled match %{rcode:'handled'} diff --git a/src/tests/unit/xlat/cond_regex.txt b/src/tests/unit/xlat/cond_regex.txt index d24ae43cfb4..ba2d6fa5492 100644 --- a/src/tests/unit/xlat/cond_regex.txt +++ b/src/tests/unit/xlat/cond_regex.txt @@ -7,17 +7,17 @@ xlat_purify &User-Name !~ /^foo\nbar$/i match (&User-Name !~ /^foo\nbar$/i) xlat_purify (&User-Name =~ "handled") -match ERROR offset 15: Expected regular expression +match ERROR offset 16: Expected regular expression xlat_purify (&User-Name == /foo/) -match ERROR offset 15: Unexpected regular expression +match ERROR offset 16: Unexpected regular expression # @todo - this should be allowed? xlat_purify &User-Name =~ &Filter-Id -match ERROR offset 14: Expected regular expression +match ERROR offset 15: Expected regular expression xlat_expr &User-Name =~ (/foo/) -match ERROR offset 14: Expected regular expression +match ERROR offset 15: Expected regular expression # # Flags @@ -65,13 +65,13 @@ xlat_purify &Tmp-String-0 =~ /foo/ match ((uint32)&Tmp-String-0 =~ /foo/) xlat_purify &Tmp-String-0 =~ /foo/ -match ERROR offset 17: Expected regular expression +match ERROR offset 18: Expected regular expression xlat_expr %{33} -match ERROR offset 2: Invalid regex reference. Must be in range 0-32 +match ERROR offset 3: Invalid regex reference. Must be in range 0-32 xlat_purify &User-Name == /foo/ -match ERROR offset 14: Unexpected regular expression +match ERROR offset 15: Unexpected regular expression # # single-quoted strings in regexes! diff --git a/src/tests/unit/xlat/purify.txt b/src/tests/unit/xlat/purify.txt index d3e8b8c497e..500123f490a 100644 --- a/src/tests/unit/xlat/purify.txt +++ b/src/tests/unit/xlat/purify.txt @@ -180,11 +180,12 @@ match false xlat_purify !true match false +# Offset 6 is wrong... but the code is structured strangely here xlat_purify -fail -match ERROR offset 9: Invalid operation on module return code +match ERROR offset 6: Invalid operation on module return code xlat_purify ~fail -match ERROR offset 9: Invalid operation on module return code +match ERROR offset 6: Invalid operation on module return code xlat_purify !fail match !%{rcode:'fail'}