]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
for length fields, just limit work_dbuff
authorAlan T. DeKok <aland@freeradius.org>
Wed, 20 Apr 2022 21:16:13 +0000 (17:16 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 21 Apr 2022 13:59:04 +0000 (09:59 -0400)
instead of encoding "too much" and checking for it later

src/lib/util/struct.c

index 1f4d533212cff9de548998d14754017e88cf306d..33f6f237d23824368fc1b80b8013169de5063695 100644 (file)
@@ -460,7 +460,7 @@ ssize_t fr_struct_to_network(fr_dbuff_t *dbuff,
                             fr_dcursor_t *parent_cursor, void *encode_ctx,
                             fr_encode_dbuff_t encode_value, fr_encode_dbuff_t encode_tlv)
 {
-       fr_dbuff_t              work_dbuff = FR_DBUFF(dbuff);
+       fr_dbuff_t              work_dbuff;
        fr_dbuff_marker_t       hdr;
        int                     offset = 0;
        unsigned int            child_num = 1;
@@ -528,12 +528,18 @@ ssize_t fr_struct_to_network(fr_dbuff_t *dbuff,
        /*
         *      Some structs are prefixed by a 16-bit length.
         */
-       if (da_is_length_field(parent)) {
-               fr_dbuff_marker(&hdr, &work_dbuff);
-
+       if (!da_is_length_field(parent)) {
+               work_dbuff = FR_DBUFF(dbuff);
+       } else {
                if (parent->flags.subtype == FLAG_LENGTH_UINT8) {
+                       work_dbuff = FR_DBUFF_MAX(dbuff, 256);
+                       fr_dbuff_marker(&hdr, &work_dbuff);
+
                        FR_DBUFF_ADVANCE_RETURN(&work_dbuff, 1);
                } else {
+                       work_dbuff = FR_DBUFF_MAX(dbuff, 65536);
+                       fr_dbuff_marker(&hdr, &work_dbuff);
+
                        FR_DBUFF_ADVANCE_RETURN(&work_dbuff, 2);
                }
                do_length = true;
@@ -788,29 +794,10 @@ done:
        }
 
        if (do_length) {
-               size_t need, max, len;
-
-               /*
-                *      @todo - maybe just limit the size of the work_dbuff.
-                */
                if (parent->flags.subtype == FLAG_LENGTH_UINT8) {
-                       need = 1;
-                       max = 256;
-               } else {
-                       need = 2;
-                       max = 65536;
-               }
-
-               len = fr_dbuff_used(&work_dbuff) - need;
-               if (len > max) {
-                       fr_strerror_const("Structure size is too large for 16-bit length field.");
-                       return -1;
-               }
-
-               if (need == 1) {
-                       fr_dbuff_in(&hdr, (uint8_t)len);
+                       fr_dbuff_in(&hdr, (uint8_t) (fr_dbuff_used(&work_dbuff) - 1));
                } else {
-                       fr_dbuff_in(&hdr, (uint16_t)len);
+                       fr_dbuff_in(&hdr, (uint16_t) (fr_dbuff_used(&work_dbuff) - 2));
                }
        }