]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
fix encoding of keyed child structures
authorAlan T. DeKok <aland@freeradius.org>
Thu, 24 Oct 2019 13:05:49 +0000 (09:05 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 24 Oct 2019 14:00:07 +0000 (10:00 -0400)
src/lib/util/struct.c
src/tests/unit/radius_struct.txt

index 3d7e57480630852ca8cc8dcb58536bf96eccd1b1..cc7d6bd9a91d20e40c7ffd721911969b9bafcfc0 100644 (file)
@@ -300,46 +300,23 @@ ssize_t fr_struct_to_network(uint8_t *out, size_t outlen,
        if (!vp || !outlen) return p - out;
 
        /*
-        *      Encode the key field based on the value of the next
-        *      attribute.  Note that there isn't much point in
-        *      converting key_da->attr into a value_box_t, and then
-        *      calling fr_value_box_to_network() to do the work.  The
-        *      code below isn't much larger in the source, but is
-        *      rather substantially simpler over all.
+        *      If our parent is a struct, AND it's parent is
+        *      the key_da, then we have a keyed struct for
+        *      the child.  Go encode it.
         */
-       if (key_da && (vp->da->parent == key_da)) {
-               switch (key_da->type) {
-               case FR_TYPE_UINT8:
-                       *key_data = key_da->attr;
-                       break;
-
-               case FR_TYPE_UINT16:
-                       if ((p - key_data) < 2) return p - out;
-
-                       key_data[0] = (key_da->attr >> 8) & 0xff;
-                       key_data[1] = key_da->attr & 0xff;
-                       break;
-
-               case FR_TYPE_UINT32:
-                       if ((p - key_data) < 4) return p - out;
-
-                       key_data[0] = (key_da->attr >> 24) & 0xff;
-                       key_data[1] = (key_da->attr >> 16) & 0xff;
-                       key_data[2] = (key_da->attr >> 8) & 0xff;
-                       key_data[3] = key_da->attr & 0xff;
-                       break;
-
-               default:
-                       return p - out;
-               }
-
-               /*
-                *      We don't need to recurse.  the caller will see
-                *      that the next attribute is of type 'struct',
-                *      and will call this function again to encode
-                *      it.
-                */
+       if (key_da &&
+           (vp->da->parent->type == FR_TYPE_STRUCT) &&
+           (vp->da->parent->parent == key_da)) {
+               len = fr_struct_to_network(p, outlen,
+                                          vp->da->parent, cursor);
+               if (len < 0) return len;
+               return (p - out) + len;
        }
+       /*
+        *      Else we have a key_da with no child struct.
+        *      Oh well.  Assume that the caller knows WTF
+        *      he's doing, and encode things as best we can.
+        */
 
        return p - out;
 }
index 31c580241b71ce133c9f3493b83d6b743eec7818..d9809770c7d0df3155cb3db2477fd6d80ec374d1 100644 (file)
@@ -57,8 +57,8 @@ match Unit-Struct4-Int1 = 1, Unit-Struct4-Int2 = 2, Unit-Struct4-Short = 4
 decode-pair ff 09 01 00 00 1a 99 05 06
 match Key-Field = Sub-Struct, Filler = 6809, Nested-Sub1 = 5, Nested-Sub2 = 6
 
-encode-pair Key-Field = Sub-Struct, Filler = 6809, Nested-Sub1 = 5, Nested-Sub2 = 6
-match ff 0b 01 00 00 1a 99 01 04 05 06
+encode-pair -
+match ff 09 01 00 00 1a 99 05 06
 
 count
 match 28