]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
cleanups and tests
authorAlan T. DeKok <aland@freeradius.org>
Tue, 29 Jul 2025 09:38:54 +0000 (05:38 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 29 Jul 2025 12:06:31 +0000 (08:06 -0400)
we might as well use "::" for FR_TYPE_ATTR, too.  This makes them
look and feel like enums, rather than adding extra-special syntax

src/bin/unit_test_attribute.c
src/lib/util/value.c
src/tests/unit/attr.txt [new file with mode: 0644]

index 8ede049f2bee46dcd9d52f779d9233b0065f2d36..6ca12faf6e2b26762c6afeb83de40d446a600760 100644 (file)
@@ -1111,8 +1111,6 @@ static size_t parse_typed_value(command_result_t *result, command_file_ctx_t *cc
                        enumv = fr_dict_root(dict);
                }
 
-               fprintf(stderr, "PARSE TYPE %s %p\n", fr_type_to_str(type), enumv);
-
                slen = fr_value_box_from_substr(box, box, type, enumv,
                                                &sbuff,
                                                &value_parse_rules_bareword_unquoted);
index 5edffdb0a515656211e5b9435a248a09666e224f..dbba61b79bea2fbe068935eccc09c3d54b0aa4bf 100644 (file)
@@ -1643,7 +1643,7 @@ ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value)
                 *      something special for attributes at other depths.
                 */
                if (value->vb_attr->depth != 1) {
-                       fr_strerror_printf("Unsupported depth '%u' for attribute %s",
+                       fr_strerror_printf("Unsupported depth '%u' for encoding attribute %s",
                                           value->vb_attr->depth, value->vb_attr->name);
                        return 0;
                }
@@ -1665,7 +1665,7 @@ ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value)
                        break;
 
                default:
-                       fr_strerror_printf("Unsupported length '%d' for attribute %s",
+                       fr_strerror_printf("Unsupported length '%d' for decoding attribute %s",
                                           value->vb_attr->flags.length, value->vb_attr->name);
                        return 0;
                }
@@ -3758,15 +3758,8 @@ int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst,
                break;          /* use generic string/octets stuff below */
 
        case FR_TYPE_ATTR:
-               if (src->vb_attr->depth != 1) {
-                       fr_strerror_printf("Unsupported depth '%d' for attribute %s",
-                                          src->vb_attr->depth, src->vb_attr->name);
-                       return 0;
-
-               }
-
                /*
-                *      Convert it to an integer of the correct lenght. Then, cast it in place.
+                *      Convert it to an integer of the correct length. Then, cast it in place.
                 */
                switch (src->vb_attr->flags.length) {
                case 1:
@@ -4996,7 +4989,7 @@ ssize_t fr_value_box_from_substr(TALLOC_CTX *ctx, fr_value_box_t *dst,
        /*
         *      Lookup any names before continuing
         */
-       if (dst_enumv && dst_enumv->flags.has_value) {
+       if (dst_enumv && dst_enumv->flags.has_value && (dst_type != FR_TYPE_ATTR)) {
                size_t                          name_len;
                fr_dict_enum_value_t const      *enumv;
 
@@ -5473,18 +5466,23 @@ parse:
                        return -1;
                }
 
-               if (!fr_sbuff_next_if_char(&our_in, '@')) {
-                       fr_strerror_const("Expected '@...' for attribute reference");
+               fr_value_box_init(dst, dst_type, dst_enumv, false);
+
+               if (!fr_sbuff_adv_past_str_literal(&our_in, "::")) {
+                       fr_strerror_const("Missing '::' for attribute reference");
                        return -1;
                }
-               
-               fr_value_box_init(dst, dst_type, dst_enumv, false);
 
-               slen = fr_dict_attr_by_name_substr(NULL, &dst->vb_attr, dst_enumv, &our_in, rules->terminals);
+               slen = fr_dict_attr_by_oid_substr(NULL, &dst->vb_attr, dst_enumv, &our_in, rules->terminals);
                if (slen <= 0) {
-                       fr_strerror_printf("Failed to find the named attribute in %s", dst_enumv->name);
-                       return -2;
+                       slen = fr_dict_attr_by_oid_substr(NULL, &dst->vb_attr, dst_enumv,
+                                                         &our_in, rules->terminals);
+                       if (slen <= 0) {
+                               fr_strerror_printf("Failed to find the named attribute in %s", dst_enumv->name);
+                               return -2;
+                       }
                }
+
                fr_assert(dst->vb_attr != NULL);
 
                FR_SBUFF_SET_RETURN(in, &our_in);
@@ -5762,15 +5760,32 @@ ssize_t fr_value_box_print(fr_sbuff_t *out, fr_value_box_t const *data, fr_sbuff
                break;
 
        case FR_TYPE_ATTR:
-               if (data->vb_attr->depth != 1) {
-                       fr_strerror_printf("Unsupported depth '%u' for attribute %s",
-                                          data->vb_attr->depth, data->vb_attr->name);
-                       return 0;
+               FR_SBUFF_IN_CHAR_RETURN(&our_out, ':', ':');
+
+               fr_assert(data->enumv != NULL);
+
+               /*
+                *      No escaping, just dump the name as-is.
+                */
+               if (!e_rules) {
+                       FR_DICT_ATTR_OID_PRINT_RETURN(&our_out, data->enumv, data->vb_attr, false);
+                       break;
                }
 
-               FR_SBUFF_IN_CHAR_RETURN(&our_out, '@');
-               FR_SBUFF_IN_ESCAPE_RETURN(&our_out, data->vb_attr->name,
-                                         strlen(data->vb_attr->name), e_rules);
+               /*
+                *      Escaping, use an intermediate buffer.  Because
+                *      we can't pipe sbuffs together.
+                */
+               {
+                       fr_sbuff_t *unescaped = NULL;
+
+                       FR_SBUFF_TALLOC_THREAD_LOCAL(&unescaped, 256, 4096);
+
+                       FR_DICT_ATTR_OID_PRINT_RETURN(unescaped, data->enumv, data->vb_attr, false);
+
+                       FR_SBUFF_IN_ESCAPE_RETURN(&our_out, fr_sbuff_start(unescaped),
+                                                 fr_sbuff_used(unescaped), e_rules);
+               }
                break;
 
        case FR_TYPE_NULL:
diff --git a/src/tests/unit/attr.txt b/src/tests/unit/attr.txt
new file mode 100644 (file)
index 0000000..b48924f
--- /dev/null
@@ -0,0 +1,14 @@
+#
+#  Parse and print data type 'attribute'
+#
+proto radius
+proto-dictionary radius
+
+value attribute ::User-Name
+match ::User-Name
+
+value attribute ::26.9.1
+match ::Vendor-Specific.Cisco.AVPair
+
+count
+match 6