]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Convert dict substr functions so they return number of bytes parsed
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 30 May 2018 06:13:54 +0000 (12:13 +0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 30 May 2018 15:14:41 +0000 (21:14 +0600)
src/include/dict.h
src/lib/util/dict.c
src/main/tmpl.c

index 58fe8cbedd1974d4ab1e8b97ea72bf2e095dc1f4..ec2bd16b6058fb712a2086575d9fd291afff7368 100644 (file)
@@ -258,7 +258,7 @@ ssize_t                     fr_dict_attr_by_oid(fr_dict_t *dict, fr_dict_attr_t const **parent,
  */
 fr_dict_attr_t const   *fr_dict_root(fr_dict_t const *dict);
 
-fr_dict_t              *fr_dict_by_protocol_substr(char const **name);
+ssize_t                        fr_dict_by_protocol_substr(fr_dict_t **out, char const *name);
 
 fr_dict_t              *fr_dict_by_protocol_name(char const *name);
 
@@ -313,7 +313,8 @@ fr_dict_attr_t const        *fr_dict_vendor_attr_by_da(fr_dict_attr_t const *da);
 
 fr_dict_attr_t const   *fr_dict_vendor_attr_by_num(fr_dict_attr_t const *vendor_root, uint32_t vendor_pen);
 
-fr_dict_attr_t const   *fr_dict_attr_by_name_substr(fr_dict_t const *dict, char const **name);
+ssize_t                        fr_dict_attr_by_name_substr(fr_dict_attr_t const **out,
+                                                   fr_dict_t const *dict, char const *name);
 
 fr_dict_attr_t const   *fr_dict_attr_by_name(fr_dict_t const *dict, char const *attr);
 
index dc315f27b9b4b53147385263ab7339eb6ea59e22..0aa0b150c637e874dd166af0c808d40241db73e6 100644 (file)
@@ -2881,10 +2881,10 @@ fr_dict_attr_t const *fr_dict_root(fr_dict_t const *dict)
  *
  * @param[in,out] name         string start.
  * @return
- *     - Attribute matching name.
- *     - NULL if no matching attribute could be found.
+ *     - <= 0 on error (offset as negative integer)
+ *     - > 0 on success (number of bytes parsed).
  */
-fr_dict_t *fr_dict_by_protocol_substr(char const **name)
+ssize_t fr_dict_by_protocol_substr(fr_dict_t **out, char const *name)
 {
        fr_dict_attr_t          root;
        fr_dict_t               find = { .root = &root };
@@ -2901,29 +2901,29 @@ fr_dict_t *fr_dict_by_protocol_substr(char const **name)
         *      Advance p until we get something that's not part of
         *      the dictionary attribute name.
         */
-       for (p = *name; fr_dict_attr_allowed_chars[(int)*p] && (*p != '.'); p++);
+       for (p = name; fr_dict_attr_allowed_chars[(int)*p] && (*p != '.'); p++);
 
-       len = p - *name;
+       len = p - name;
        if (len > FR_DICT_ATTR_MAX_NAME_LEN) {
                fr_strerror_printf("Attribute name too long");
-               return NULL;
+               return -(FR_DICT_ATTR_MAX_NAME_LEN);
        }
 
        root.name = talloc_bstrndup(NULL, *name, len);
        if (!root.name) {
                fr_strerror_printf("Out of memory");
-               return NULL;
+               return 0;
        }
        dict = fr_hash_table_finddata(protocol_by_name, &find);
        talloc_const_free(root.name);
 
        if (!dict) {
-               fr_strerror_printf("Unknown protocol '%.*s'", (int) len, *name);
-               return NULL;
+               fr_strerror_printf("Unknown protocol '%.*s'", (int) len, name);
+               return 0;
        }
-       *name = p;
+       *out = dict;
 
-       return dict;
+       return p - name;
 }
 
 /** Lookup a protocol by its name
@@ -3209,14 +3209,15 @@ fr_dict_attr_t const *fr_dict_vendor_attr_by_num(fr_dict_attr_t const *vendor_ro
  * If the attribute does not exist, don't advance the pointer and return
  * NULL.
  *
+ * @param[out] out             Where to store the resolve attribute.
  * @param[in] dict             of protocol context we're operating in.
  *                             If NULL the internal dictionary will be used.
- * @param[in,out] name         string start.
+ * @param[in] name             string start.
  * @return
- *     - Attribute matching name.
- *     - NULL if no matching attribute could be found.
+ *     - <= 0 on failure.
+ *     - The number of bytes of name consumed on success.
  */
-fr_dict_attr_t const *fr_dict_attr_by_name_substr(fr_dict_t const *dict, char const **name)
+ssize_t fr_dict_attr_by_name_substr(fr_dict_attr_t const **out, fr_dict_t const *dict, char const *name)
 {
        fr_dict_attr_t          find;
        fr_dict_attr_t const    *da;
@@ -3232,29 +3233,30 @@ fr_dict_attr_t const *fr_dict_attr_by_name_substr(fr_dict_t const *dict, char co
         *      Advance p until we get something that's not part of
         *      the dictionary attribute name.
         */
-       for (p = *name; fr_dict_attr_allowed_chars[(int)*p]; p++);
+       for (p = name; fr_dict_attr_allowed_chars[(int)*p]; p++);
 
-       len = p - *name;
+       len = p - name;
        if (len > FR_DICT_ATTR_MAX_NAME_LEN) {
                fr_strerror_printf("Attribute name too long");
-               return NULL;
+               return -(FR_DICT_ATTR_MAX_NAME_LEN);
        }
 
-       find.name = talloc_bstrndup(NULL, *name, len);
+       find.name = talloc_bstrndup(NULL, name, len);
        if (!find.name) {
                fr_strerror_printf("Out of memory");
-               return NULL;
+               return 0;
        }
        da = fr_hash_table_finddata(dict->attributes_by_name, &find);
        talloc_const_free(find.name);
 
        if (!da) {
-               fr_strerror_printf("Unknown attribute '%.*s'", (int) len, *name);
-               return NULL;
+               fr_strerror_printf("Unknown attribute '%.*s'", (int) len, name);
+               return 0;
        }
-       *name = p;
 
-       return da;
+       *out = da;
+
+       return p - name;
 }
 
 /** Locate a #fr_dict_attr_t by its name
@@ -3703,6 +3705,7 @@ static fr_dict_attr_t const *dict_resolve_reference(fr_dict_t *dict, char const
        char const              *p = ref, *q, *end = p + strlen(ref);
        fr_dict_t               *proto_dict;
        fr_dict_attr_t const    *da;
+       ssize_t                 slen;
 
        /*
         *      If the reference does not begin with .
@@ -3746,11 +3749,13 @@ static fr_dict_attr_t const *dict_resolve_reference(fr_dict_t *dict, char const
        if (*p == '.') {
                p++;
 
-               da = fr_dict_attr_by_name_substr(proto_dict, &p);
-               if (!da) {
+               slen = fr_dict_attr_by_name_substr(&da, proto_dict, p);
+               if (slen <= 0) {
                        fr_strerror_printf("Referenced attribute \"%s\" not found", p);
                        return NULL;
                }
+
+               p += slen;
        }
 
        da = fr_dict_root(proto_dict);
index 220b41f47fd6b93abfbf6ce626a508cfa464625a..60fec3cc8141a8dac8781a504729c1249bda9fa1 100644 (file)
@@ -666,8 +666,8 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, vp_tmpl_t **out, char const *nam
         *      Look up by name, *including* any Attr-1.2.3.4 which was created when
         *      parsing the configuration files.
         */
-       vpt->tmpl_da = fr_dict_attr_by_name_substr(NULL, &p);
-       if (!vpt->tmpl_da) {
+       slen = fr_dict_attr_by_name_substr(&vpt->tmpl_da, NULL, p);
+       if (slen <= 0) {
                char const *q;
 
                fr_strerror();  /* Clear out any existing errors */
@@ -735,6 +735,11 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, vp_tmpl_t **out, char const *nam
                goto do_num;
        }
 
+       /*
+        *      Parsing was successful, so advance the pointer
+        */
+       p += slen;
+
        /*
         *      If it's an attribute, look for a tag.
         *
@@ -742,7 +747,7 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, vp_tmpl_t **out, char const *nam
         *      isn't tagged.  This lets us print more useful error
         *      messages.
         */
-       else if (*p == ':') {
+       if (*p == ':') {
                char *q;
 
                if (!vpt->tmpl_da->flags.has_tag) { /* Lists don't have a da */
@@ -770,12 +775,12 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, vp_tmpl_t **out, char const *nam
                        p = q;
                }
 
-               /*
-                *      The attribute is tagged, but the admin didn't
-                *      specify one.  This means it's likely a
-                *      "search" thingy.. i.e. "find me ANY attribute,
-                *      no matter what the tag".
-                */
+       /*
+        *      The attribute is tagged, but the admin didn't
+        *      specify one.  This means it's likely a
+        *      "search" thingy.. i.e. "find me ANY attribute,
+        *      no matter what the tag".
+        */
        } else if (vpt->tmpl_da->flags.has_tag) {
                vpt->tmpl_tag = TAG_ANY;
        }