]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Internal decoder should always build nested attribute structure for TLVs
authorNick Porter <nick@portercomputing.co.uk>
Thu, 4 Aug 2022 10:06:53 +0000 (11:06 +0100)
committerNick Porter <nick@portercomputing.co.uk>
Wed, 17 Aug 2022 07:26:02 +0000 (08:26 +0100)
src/protocols/internal/decode.c

index 14c178d12d91c6333692f7015af9bada9a667452..8cb34bc9b875866a6172dd4d490add68fd86bac6 100644 (file)
@@ -70,13 +70,17 @@ static ssize_t internal_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *head, fr_dic
 {
 
        ssize_t         slen;
-       fr_pair_list_t  children;
-       fr_dcursor_t    cursor;
        fr_dbuff_t      work_dbuff = FR_DBUFF(dbuff);
+       fr_pair_t       *tlv;
 
        FR_PROTO_TRACE("Decoding TLV - %s (%zu bytes)", parent_da->name, fr_dbuff_len(&work_dbuff));
 
-       fr_pair_list_init(&children);
+       /*
+        *      Create intermediary TLV VP to retain
+        *      the nesting structure
+        */
+       tlv = fr_pair_afrom_da(ctx, parent_da);
+       if (!tlv) return PAIR_DECODE_OOM;
 
        /*
         *      Decode all the children of this TLV
@@ -85,32 +89,15 @@ static ssize_t internal_decode_tlv(TALLOC_CTX *ctx, fr_pair_list_t *head, fr_dic
                FR_PROTO_HEX_MARKER(fr_dbuff_start(&work_dbuff), fr_dbuff_len(&work_dbuff),
                                    fr_dbuff_remaining(&work_dbuff), "Decoding child");
 
-               slen = internal_decode_pair(ctx, &children, parent_da, &work_dbuff, decode_ctx);
-               if (slen <= 0) return slen;
-       }
-
-       /*
-        *      If decoding produced more than one child
-        *      we need to do an intermediary TLV
-        *      VP to retain the nesting structure.
-        */
-       if (fr_pair_dcursor_init(&cursor, &children) && fr_dcursor_next_peek(&cursor)) {
-               fr_pair_t       *tlv;
-
-               tlv = fr_pair_afrom_da(ctx, parent_da);
-               if (!tlv) return PAIR_DECODE_OOM;
-
-               while (fr_dcursor_head(&cursor)) {
-                       FR_PROTO_TRACE("Moving %s into %s",
-                                      ((fr_pair_t *)fr_dcursor_head(&cursor))->da->name, tlv->da->name);
-                       fr_pair_append(&tlv->vp_group, talloc_reparent(ctx, tlv, fr_dcursor_remove(&cursor)));
+               slen = internal_decode_pair(tlv, &tlv->vp_group, parent_da, &work_dbuff, decode_ctx);
+               if (slen <= 0) {
+                       talloc_free(tlv);
+                       return slen;
                }
-
-               fr_pair_append(head, tlv);
-       } else {
-               fr_pair_append(head, fr_dcursor_remove(&cursor));
        }
 
+       fr_pair_append(head, tlv);
+
        return fr_dbuff_set(dbuff, &work_dbuff);
 }