at_rules = &t_rules->attr;
/*
- * The caller wants to know the default namespace for
- * resolving the attribute.
- *
- * @todo - why not use dict_def if it's set? Tho TBH we
- * should probably just remove dict_def, and always use "namespace".
+ * The caller wants to know the default namespace for resolving the attribute.
*/
if (namespace) {
if (at_rules->namespace) {
- /*
- * If the namespace is FR_TYPE_GROUP use the correct namespace
- */
- *namespace = at_rules->namespace->type == FR_TYPE_GROUP ? fr_dict_attr_ref(at_rules->namespace) : at_rules->namespace;
+ if (request_attr_is_list(at_rules->namespace)) {
+ /*
+ * If the namespace is a list attribute, then reset it to NULL, so that the rest of the
+ * code will use the default dictionary.
+ */
+ if (!at_rules->dict_def) {
+ fr_strerror_const("No dictionary was set - cannot parse attributes");
+ FR_SBUFF_ERROR_RETURN(&our_in);
+ }
+ *namespace = NULL;
+
+ } else if (at_rules->namespace->type != FR_TYPE_GROUP) {
+ /*
+ * If the namespace is a structural type, then use the namespace is this
+ * attribute. We can then parse children of the attribute.
+ */
+ *namespace = at_rules->namespace;
+
+ } else if (at_rules->namespace->flags.internal && at_rules->dict_def) {
+ /*
+ * If the group is internal, AND we have a default dictionary, reset the
+ * namespace to NULL, so that the rest of the code will use the default
+ * dictionary.
+ */
+ *namespace = NULL;
+
+ } else {
+ /*
+ * The namespace is a non-internal group. Update the namespace to be
+ * whereever the group is pointing to.
+ */
+ *namespace = fr_dict_attr_ref(at_rules->namespace);
+ }
+
} else {
*namespace = NULL;
}
/*
* We're in a name space, OR lists are forbidden, don't allow list qualifiers.
*/
- if (at_rules->namespace || (at_rules->list_presence == TMPL_ATTR_LIST_FORBID)) {
+ if (*namespace || (at_rules->list_presence == TMPL_ATTR_LIST_FORBID)) {
if (fr_sbuff_is_str_literal(&our_in, "outer.") ||
fr_sbuff_is_str_literal(&our_in, "parent.")) {
fr_strerror_const("request list qualifiers are not allowed here");
map_t *child;
/*
- * Don't update namespace for reply += { ... }
- *
- * Do update namespace for reply.foo += { ... }
- *
- * Don't update if the LHS is an internal group.
+ * Reset the namespace to be this attribute. The tmpl tokenizer will take care of
+ * figuring out if this is a group, TLV, dictionary switch, etc.
*/
- if ((tmpl_attr_num_elements(map->lhs) > 1) && (t_rules.attr.list_def != parent_da) &&
- !((parent_da->type == FR_TYPE_GROUP) && parent_da->flags.internal)) {
- t_rules.attr.namespace = parent_da;
- }
+ t_rules.attr.namespace = parent_da;
if (map_afrom_cs_edit(map, &map->child, cs, &t_rules, &t_rules, unlang_fixup_edit, map, 256) < 0) {
goto fail;