]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add and use fr_pair_dcursor_child_iter_init()
authorAlan T. DeKok <aland@freeradius.org>
Tue, 12 Sep 2023 18:02:26 +0000 (14:02 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 12 Sep 2023 18:02:26 +0000 (14:02 -0400)
all of the encoders previously just called fr_pair_dcursor_init()
for child cursors.  Which meant that the iterator could return
internal attributes.

The child cursor now uses the same iterator as the parent cursor.
This ensures that it only returns the correct encodable attributes
for this protocol.

src/lib/util/dcursor.h
src/lib/util/pair.h
src/protocols/dhcpv4/encode.c
src/protocols/dhcpv6/encode.c
src/protocols/dns/encode.c
src/protocols/radius/encode.c

index acfc4e2562f6b026b022843c4dd21e5a66349bfb..961eae09c2876475730fd0626bcf808ceeab125f 100644 (file)
@@ -195,6 +195,33 @@ static inline void fr_dcursor_copy(fr_dcursor_t *out, fr_dcursor_t const *in)
        if (in->copy) fr_dcursor_copy(out, in);
 }
 
+/** Copy a read-only iterator from a parent to a child cursor
+ *
+ * @param[out] out     Where to copy the cursor to.
+ * @param[in] in       cursor to copy.
+ *
+ * @hidecallergraph
+ */
+CC_HINT(nonnull)
+static inline void fr_dcursor_copy_iter(fr_dcursor_t *out, fr_dcursor_t const *in)
+{
+       fr_assert(!out->iter);
+       fr_assert(!out->iter_uctx);
+
+       out->iter = in->iter;
+       out->iter_uctx = in->iter_uctx;
+
+#ifndef NDEBUG
+       /*
+        *      The output cursor has to be read-only.
+        */
+       out->insert = NULL;
+       out->remove = NULL;
+       out->mod_uctx = NULL;
+       out->copy = NULL;
+#endif
+}
+
 /** Rewind cursor to the start of the list
  *
  * @param[in] cursor   to operate on.
index 8f7562517a8e9f2c06f0d7f13cafb49cd53ab332..6658354325f8b6a068eb421ff783cae157b5e522 100644 (file)
@@ -580,6 +580,27 @@ fr_pair_t  *_fr_pair_dcursor_iter_init(fr_dcursor_t *cursor, fr_pair_list_t const
 fr_pair_t      *_fr_pair_dcursor_init(fr_dcursor_t *cursor, fr_pair_list_t const *list,
                                       bool is_const) CC_HINT(nonnull);
 
+/** Initializes a child dcursor from a parent cursor, with an iteration function.
+ *
+ * Filters can be applied later with fr_dcursor_filter_set.
+ *
+ * @note This is the only way to use a dcursor in non-const mode with fr_pair_list_t.
+ *
+ * @param[out] cursor  to initialise.
+ * @param[in] list     to iterate over.
+ * @param[in] parent   parent cursor to take the iterator from
+ * @return
+ *     - NULL if src does not point to any items.
+ *     - The first pair in the list.
+ */
+static inline fr_pair_t        *fr_pair_dcursor_child_iter_init(fr_dcursor_t *cursor, fr_pair_list_t const *list, fr_dcursor_t const *parent)
+{
+       fr_pair_t *vp = fr_pair_dcursor_init(cursor, list);
+
+       fr_dcursor_copy_iter(cursor, parent);
+       return vp;
+}
+
 /** Initialise a cursor that will return only attributes matching the specified #fr_dict_attr_t
  *
  * @param[in] _cursor  to initialise.
index dce93f68043fcc9dc011492ad12c586f96842b05..c8c61847ce3a4c04e8519444ebe443477223e4f0 100644 (file)
@@ -386,7 +386,7 @@ static ssize_t encode_child(fr_dbuff_t *dbuff,
 
        fr_assert(fr_type_is_structural(vp->vp_type));
 
-       fr_pair_dcursor_init(&child_cursor, &vp->vp_group);
+       fr_pair_dcursor_child_iter_init(&child_cursor, &vp->vp_group, cursor);
        work_dbuff = FR_DBUFF(dbuff);
 
        while ((vp = fr_dcursor_current(&child_cursor)) != NULL) {
index 110b67e222b95f7ea57f1c09f568a68868ec2724..7e95163b117ea61026e973115610fedbf5f70925 100644 (file)
@@ -283,7 +283,7 @@ static ssize_t encode_value(fr_dbuff_t *dbuff,
                 *      Encode the child options.
                 */
                if (!fr_pair_list_empty(&vp->vp_group)) {
-                       (void) fr_pair_dcursor_init(&child_cursor, &vp->vp_group);
+                       (void) fr_pair_dcursor_child_iter_init(&child_cursor, &vp->vp_group, cursor);
 
                        while (fr_dcursor_current(&child_cursor) != NULL) {
                                slen = fr_dhcpv6_encode_option(&work_dbuff, &child_cursor, encode_ctx);
@@ -400,7 +400,7 @@ static ssize_t encode_child(fr_dbuff_t *dbuff,
 
        fr_assert(fr_type_is_structural(vp->vp_type));
 
-       fr_pair_dcursor_init(&child_cursor, &vp->vp_group);
+       fr_pair_dcursor_child_iter_init(&child_cursor, &vp->vp_group, cursor);
        work_dbuff = FR_DBUFF(dbuff);
 
        while ((vp = fr_dcursor_current(&child_cursor)) != NULL) {
index bef5418b7842f84bc18fb2f25943a303c01d6e18..ba782477a7a0937e7157f6dd0d6e07d15a532a76 100644 (file)
@@ -95,7 +95,7 @@ static ssize_t encode_value(fr_dbuff_t *dbuff,
        if (vp->vp_type == FR_TYPE_STRUCT) {
                fr_dcursor_t child_cursor;
 
-               fr_pair_dcursor_init(&child_cursor, &vp->vp_group);
+               fr_pair_dcursor_child_iter_init(&child_cursor, &vp->vp_group, cursor);
 
                slen = fr_struct_to_network(&work_dbuff, da_stack, depth, &child_cursor, encode_ctx, encode_value, encode_child);
                if (slen < 0) return slen;
@@ -248,7 +248,7 @@ static ssize_t encode_child(fr_dbuff_t *dbuff,
 
        fr_assert(fr_type_is_structural(vp->vp_type));
 
-       fr_pair_dcursor_init(&child_cursor, &vp->vp_group);
+       fr_pair_dcursor_child_iter_init(&child_cursor, &vp->vp_group, cursor);
        work_dbuff = FR_DBUFF(dbuff);
 
        while ((vp = fr_dcursor_current(&child_cursor)) != NULL) {
@@ -391,7 +391,7 @@ static ssize_t fr_dns_encode_rr(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *e
        if (vp->vp_type == FR_TYPE_STRUCT) {
                fr_dcursor_t child_cursor;
 
-               fr_pair_dcursor_init(&child_cursor, &vp->vp_group);
+               fr_pair_dcursor_child_iter_init(&child_cursor, &vp->vp_group, cursor);
 
                slen = fr_struct_to_network(&work_dbuff, &da_stack, 0, &child_cursor, encode_ctx, encode_value, encode_child);
                if (slen <= 0) return slen;
index 0a6ac3d57539d287679bf30f0c417b973491cc04..0300ec8b2194816d1e6dc2e044b799598b772be9 100644 (file)
@@ -251,7 +251,7 @@ static ssize_t encode_tlv(fr_dbuff_t *dbuff,
                                return PAIR_ENCODE_SKIPPED;
                        }
 
-                       fr_pair_dcursor_init(&child_cursor, &vp->vp_group);
+                       fr_pair_dcursor_child_iter_init(&child_cursor, &vp->vp_group, cursor);
                        vp = fr_dcursor_current(&child_cursor);
                        fr_proto_da_stack_build(da_stack, vp->da);
 
@@ -855,7 +855,7 @@ static ssize_t encode_extended_nested(fr_dbuff_t *dbuff,
        parent = fr_dcursor_current(cursor);
        fr_assert(fr_type_is_structural(parent->vp_type));
 
-       (void) fr_pair_dcursor_init(&child_cursor, &parent->vp_group);
+       (void) fr_pair_dcursor_child_iter_init(&child_cursor, &parent->vp_group, cursor);
 
        FR_PROTO_STACK_PRINT(da_stack, depth);
 
@@ -1190,7 +1190,7 @@ static ssize_t encode_vendor(fr_dbuff_t *dbuff,
        fr_assert(vp->da == da);
        work_dbuff = FR_DBUFF(dbuff);
 
-       fr_pair_dcursor_init(&child_cursor, &vp->vp_group);
+       fr_pair_dcursor_child_iter_init(&child_cursor, &vp->vp_group, cursor);
        while ((vp = fr_dcursor_current(&child_cursor)) != NULL) {
                fr_proto_da_stack_build(da_stack, vp->da);
 
@@ -1252,7 +1252,7 @@ static ssize_t encode_vsa(fr_dbuff_t *dbuff,
         *      Loop over the children of this Vendor-Specific
         *      attribute.
         */
-       fr_pair_dcursor_init(&child_cursor, &vp->vp_group);
+       fr_pair_dcursor_child_iter_init(&child_cursor, &vp->vp_group, cursor);
        while ((vp = fr_dcursor_current(&child_cursor)) != NULL) {
                fr_proto_da_stack_build(da_stack, vp->da);