]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Switch the majority of xlat functions and condition functions to returning fr_sbuff_error
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 4 Sep 2022 20:51:21 +0000 (16:51 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 4 Sep 2022 20:51:21 +0000 (16:51 -0400)
21 files changed:
src/bin/unit_test_attribute.c
src/lib/server/cond_tokenize.c
src/lib/server/map.c
src/lib/server/tmpl_dcursor_tests.c
src/lib/server/tmpl_tokenize.c
src/lib/unlang/xlat.h
src/lib/unlang/xlat_expr.c
src/lib/unlang/xlat_tokenize.c
src/lib/util/base16.c
src/lib/util/base16.h
src/lib/util/dict.h
src/lib/util/dict_unknown.c
src/lib/util/dict_util.c
src/lib/util/pair_legacy.c
src/lib/util/sbuff.h
src/tests/unit/condition/base.txt
src/tests/unit/condition/regex.txt
src/tests/unit/xlat/base.txt
src/tests/unit/xlat/cond_base.txt
src/tests/unit/xlat/cond_regex.txt
src/tests/unit/xlat/purify.txt

index c578fd2f23d1ebfa01195e3bf348e5392d293e08..a352c0f52b4e7a71b89d8a3b9d6dad199acd6b60 100644 (file)
@@ -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)
index 127563ff107ea3f432d032bca2a671bd447b4d31..9858722e7deb2c9331171b4c887c0cb4f94e776d 100644 (file)
@@ -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;
index 7496693083fab4c6efb2fbcbfc99a4434d5635f8..1b8b1ac16acae56356a493fc8d0eea0394382cef 100644 (file)
@@ -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);
        }
 
        /*
index 2c4b4469d82ebfe37924725be5540c78575e2bc4..24382049a283eca0647111c54191fe6cd60086e7 100644 (file)
@@ -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)
 
index b81ec321f0c4e8b6d6b6c6fd4a67f8269ee94686..c974bf427843065062ebdf2de9e6975051bff9fa 100644 (file)
@@ -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));
 
index 44052de623ec90b6c7c4d7caad18a91615a2427f..fbfb5a24f4f756ec9ff47c9dccb52ead6643f61b 100644 (file)
@@ -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)
index 9bef82b66e904bcc6bbc51cf6eba0e6a55cb9a4d..c96a9e02df5e759693ec7fd76331149da3dfee05 100644 (file)
@@ -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;
index 60baa5254249970edae945b1971ab2328b89a0d7..5f92723bb8ecb10a563a1f74ad14e4bd6c3defd5 100644 (file)
@@ -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);
        }
 
        /*
index 4eeeb455c65330bc427a467a3c6ae286a51f5e22..51471fc44efa8296268eecf251720331ae187a68 100644 (file)
@@ -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);
index 917b0a7a04f70ff0c5ca70eda339be85ee48c4d8..f5638f80ae3ead4db3055e61fa89c98b04797b6f 100644 (file)
@@ -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)
index 5cf38743be03d26f3598824d4d5599e2b6bf9402..5b4aa2d3f4cccbfd04306102b1c11e3600770117 100644 (file)
@@ -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);
index 6756802a63163d83c9985205678d601a970c18d7..9ae9a0b1143d05b3ed2048ca38c08c266b6d32a9 100644 (file)
@@ -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
index f98559cc9303a3f1e9d38cf738e8c0c09d7a2764..195726ecfca25d11ebaa52e2c8e1093ed736815e 100644 (file)
  */
 RCSID("$Id$")
 
+#define _DICT_PRIVATE 1
+
+#include <freeradius-devel/util/atexit.h>
 #include <freeradius-devel/util/conf.h>
+#include <freeradius-devel/util/dict.h>
 #include <freeradius-devel/util/dict_fixup_priv.h>
 #include <freeradius-devel/util/proto.h>
 #include <freeradius-devel/util/rand.h>
+#include <freeradius-devel/util/sbuff.h>
 #include <freeradius-devel/util/syserror.h>
-#include <freeradius-devel/util/atexit.h>
 
 #ifdef HAVE_SYS_STAT_H
 #  include <sys/stat.h>
@@ -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, "<INVALID>"),
-                                  (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);
        }
 
        /*
index e6417b73034624b5d4bdfb140d769049c4665507..c69c7529437a3085e8082940e04f0815eef75b35 100644 (file)
@@ -20,6 +20,7 @@
  *
  * @copyright 2000,2006,2015 The FreeRADIUS server project
  */
+#include "lib/util/dict.h"
 RCSID("$Id$")
 
 #include <freeradius-devel/util/pair.h>
@@ -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:
index 245c766addcf3d772124d5c9fc65885d4e3e63d2..199dbbcc44a68891fb51c188af15e7b48a35dac4 100644 (file)
@@ -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
  *
  */
index 354bee61aadf47684e70f98fee8cdb3648d29828..da42eb8c9bf0aea42fd77df48984054bab051894 100644 (file)
@@ -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 <ipv6addr>::1
-match ERROR offset 0: Invalid cast from ipv6addr to bool.  Unsupported
+match ERROR offset 1: Invalid cast from ipv6addr to bool.  Unsupported
 
 condition <ipaddr>&Filter-Id == &Framed-IP-Address
 match <ipaddr>&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 <ipaddr>&Framed-IP-Address == 127.0.0.1
@@ -222,7 +222,7 @@ condition <integer>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 <ipaddr>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
index fdc048458441286e3a5f8166541a61b5b0af348d..24c8bbc794a357589df4941224682cac717afd6e 100644 (file)
@@ -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 <string>&Tmp-Integer-0 =~ /%{Tmp-Integer-0}/
 #  Cannot add a bad cast
 #
 condition <integer>&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 =~ <integer>/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
index d968aac0dedb1c9607ecebd95bd8f820f82ea5fc..1b8bcd0980d7d062c008906dc39e824d7b76556a 100644 (file)
@@ -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
index 87ff20218177242ced00e6219212d8ae795dbe9e..83c3a9b8b5d804a69ef06470967d7cd2343e487a 100644 (file)
@@ -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 <ipaddr>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'}
index d24ae43cfb439ec5a9e08361e27cef15813cebe1..ba2d6fa5492c5a21b991f34bfebbfad5c4bc1797 100644 (file)
@@ -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 <integer>&Tmp-String-0 =~ /foo/
 match ((uint32)&Tmp-String-0 =~ /foo/)
 
 xlat_purify &Tmp-String-0 =~ <integer>/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!
index d3e8b8c497e76c02fa0409af2a3b836855aa6f85..500123f490a99f30724c6ff47fc9c5c6e8a716e0 100644 (file)
@@ -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'}