]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
allow '@' references for value box parser
authorAlan T. DeKok <aland@freeradius.org>
Mon, 4 Aug 2025 12:49:34 +0000 (08:49 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 4 Aug 2025 12:49:34 +0000 (08:49 -0400)
the reference can't change dictionaries

src/lib/util/value.c

index 27e47d14116c38dfd149766aebda4de331fa7948..751d02f3af47e42a7ca2cb719aa32dbfc05f5db4 100644 (file)
@@ -5618,7 +5618,46 @@ parse:
 
                fr_value_box_init(dst, dst_type, dst_enumv, false);
 
-               if (fr_sbuff_adv_past_str_literal(&our_in, "::")) {
+               /*
+                *      Allow '@' references in values.
+                */
+               if (fr_sbuff_is_char(&our_in, '@')) {
+                       size_t len;
+                       fr_sbuff_marker_t m;
+
+                       fr_sbuff_marker(&m, &our_in);
+                       fr_sbuff_advance(&our_in, 1); /* '@' is not an allowed character for dictionary names */
+
+                       len = fr_sbuff_adv_past_allowed(&our_in, fr_sbuff_remaining(&our_in),
+                                                       fr_dict_attr_nested_allowed_chars, NULL);
+                       fr_sbuff_set(&our_in, &m);
+                       fr_sbuff_marker_release(&m);
+
+                       len++;  /* account for '@' */
+
+                       /*
+                        *      This function needs the '@'.
+                        */
+                       if (fr_dict_protocol_reference(&dst->vb_attr, fr_dict_root(dst_enumv->dict), &FR_SBUFF_IN(fr_sbuff_current(&our_in), len)) < 0) {
+                               return -1;
+                       }
+
+                       if (!dst->vb_attr) {
+                               fr_strerror_printf("Failed to find attribute reference %.*s", (int) len, fr_sbuff_current(&our_in));
+                               return -1;
+                       }
+
+                       fr_assert(dst->vb_attr != NULL);
+
+                       if (dst->vb_attr->dict != dst_enumv->dict) {
+                               fr_strerror_const("Type 'attribute' cannot reference a different protocol");
+                               return -1;
+                       }
+
+                       fr_sbuff_advance(&our_in, len);
+                       FR_SBUFF_SET_RETURN(in, &our_in);
+
+               } else if (fr_sbuff_adv_past_str_literal(&our_in, "::")) {
 
                        slen = fr_dict_attr_by_oid_substr(NULL, &dst->vb_attr, dst_enumv, &our_in, rules->terminals);
                        if (slen > 0) {