]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Remove un-needed uses of tmpl_is_list()
authorNick Porter <nick@portercomputing.co.uk>
Thu, 26 Jan 2023 11:56:22 +0000 (11:56 +0000)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 9 Feb 2023 18:37:29 +0000 (12:37 -0600)
13 files changed:
src/lib/server/cond_tokenize.c
src/lib/server/map.c
src/lib/server/map_async.c
src/lib/server/tmpl.h
src/lib/server/tmpl_dcursor.c
src/lib/server/tmpl_eval.c
src/lib/server/tmpl_tokenize.c
src/lib/unlang/compile.c
src/lib/unlang/subrequest.c
src/lib/unlang/xlat_eval.c
src/lib/unlang/xlat_tokenize.c
src/modules/rlm_cache/rlm_cache.c
src/modules/rlm_smtp/rlm_smtp.c

index cb8dba4150282caac0a2258b0d5e03cdcb342b72..9e558a40850926de0a13986e8b0e0ed581570833 100644 (file)
@@ -222,7 +222,6 @@ int fr_cond_promote_types(fr_cond_t *c, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs
         */
        if (tmpl_contains_regex(c->data.map->rhs)) {
                fr_assert((c->data.map->op == T_OP_REG_EQ) || (c->data.map->op == T_OP_REG_NE));
-               fr_assert(!tmpl_is_list(c->data.map->lhs));
                fr_assert(fr_type_is_null(tmpl_rules_cast(c->data.map->rhs)));
 
                /*
index 652b0ca00c6ea2c9266b8c2691792927f0789f98..007d3b4cf485dbe51725e23f1a9186a3cb9863f2 100644 (file)
@@ -1362,7 +1362,7 @@ static int map_exec_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *reque
 
        fr_assert(map->rhs);            /* Quite clang scan */
        fr_assert(tmpl_is_exec(map->rhs));
-       fr_assert(tmpl_is_attr(map->lhs) || tmpl_is_list(map->lhs));
+       fr_assert(tmpl_is_attr(map->lhs));
 
        /*
         *      We always put the request pairs into the environment
@@ -1375,8 +1375,7 @@ static int map_exec_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *reque
         *      if dst is an attribute, then we create an attribute of that type and then
         *      call fr_pair_value_from_str on the output of the script.
         */
-       result = radius_exec_program_legacy(ctx, answer, sizeof(answer),
-                                    tmpl_is_list(map->lhs) ? &output_pairs : NULL,
+       result = radius_exec_program_legacy(ctx, answer, sizeof(answer), NULL,
                                     request, map->rhs->name, input_pairs ? input_pairs : NULL,
                                     true, true, fr_time_delta_from_sec(EXEC_TIMEOUT));
        talloc_free(expanded);
@@ -1443,7 +1442,7 @@ int map_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, map_t co
        MAP_VERIFY(map);
        if (!fr_cond_assert(map->lhs != NULL)) return -1;
 
-       fr_assert(tmpl_is_list(map->lhs) || tmpl_is_attr(map->lhs));
+       fr_assert(tmpl_is_attr(map->lhs));
 
        /*
         *      Special case for !*, we don't need to parse RHS as this is a unary operator.
@@ -1513,8 +1512,8 @@ int map_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, map_t co
         *      to allocate any attributes, just finding the current list, and change
         *      the op.
         */
-       if ((tmpl_is_list(map->lhs) || (tmpl_contains_attr(map->lhs) && tmpl_attr_tail_da_is_structural(map->lhs))) &&
-           (tmpl_is_list(map->rhs) || (tmpl_contains_attr(map->rhs) && tmpl_attr_tail_da_is_structural(map->rhs)))) {
+       if ((tmpl_contains_attr(map->lhs) && tmpl_attr_tail_da_is_structural(map->lhs)) &&
+           (tmpl_contains_attr(map->rhs) && tmpl_attr_tail_da_is_structural(map->rhs))) {
                fr_pair_list_t *from = NULL;
 
                if (tmpl_request_ptr(&context, tmpl_request(map->rhs)) == 0) {
@@ -1597,8 +1596,7 @@ int map_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, map_t co
                fr_pair_t *vp;
                fr_dcursor_t from;
 
-               fr_assert((tmpl_is_attr(map->lhs) && tmpl_attr_tail_da(map->lhs)) ||
-                          (tmpl_is_list(map->lhs) && !tmpl_attr_tail_da(map->lhs)));
+               fr_assert(tmpl_is_attr(map->lhs) && tmpl_attr_tail_da(map->lhs));
 
                /*
                 * @todo should log error, and return -1 for v3.1 (causes update to fail)
@@ -1792,7 +1790,7 @@ int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t f
                        rcode = -1;
                        goto finish;
                }
-               fr_assert(tmpl_is_attr(exp_lhs) || tmpl_is_list(exp_lhs));
+               fr_assert(tmpl_is_attr(exp_lhs));
 
                memcpy(&exp_map, map, sizeof(exp_map));
                exp_map.lhs = exp_lhs;
@@ -1810,8 +1808,7 @@ int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t f
         *      Sanity check inputs.  We can have a list or attribute
         *      as a destination.
         */
-       if (!tmpl_is_list(map->lhs) &&
-           !tmpl_is_attr(map->lhs)) {
+       if (!tmpl_is_attr(map->lhs)) {
                REDEBUG("Left side \"%.*s\" of map should be an attr or list but is an %s",
                        (int)map->lhs->len, map->lhs->name,
                        tmpl_type_to_str(map->lhs->type));
index a3cf66e3aa466a8bea7448f7290f4dd0d4da2b91..54b8ae5d0858a2ccaf1170b5ac2d439ac10b70ab 100644 (file)
@@ -265,9 +265,8 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out,
        if (!fr_cond_assert(original->lhs != NULL)) return -1;
        if (!fr_cond_assert(original->rhs != NULL)) return -1;
 
-       fr_assert(tmpl_is_list(original->lhs) ||
-                  tmpl_is_attr(original->lhs) ||
-                  tmpl_is_xlat(original->lhs));
+       fr_assert(tmpl_is_attr(original->lhs) ||
+                 tmpl_is_xlat(original->lhs));
 
        *out = NULL;
        fr_value_box_list_init(&head);
@@ -333,7 +332,7 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out,
                        fr_value_box_list_talloc_free(lhs_result);
                        goto error;
                }
-               fr_assert(tmpl_is_attr(mutated->lhs) || tmpl_is_list(mutated->lhs));
+               fr_assert(tmpl_is_attr(mutated->lhs));
        }
                break;
 
@@ -541,8 +540,7 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out,
                int                     err;
 
                fr_assert(fr_value_box_list_empty(rhs_result));
-               fr_assert((tmpl_is_attr(mutated->lhs) && tmpl_attr_tail_da(mutated->lhs)) ||
-                          (tmpl_is_list(mutated->lhs) && !tmpl_attr_tail_da(mutated->lhs)));
+               fr_assert(tmpl_is_attr(mutated->lhs) && tmpl_attr_tail_da(mutated->lhs));
 
                /*
                 *      Check source list
@@ -966,7 +964,7 @@ int map_list_mod_apply(request_t *request, vp_list_mod_t const *vlm)
                fr_assert(mod->lhs != NULL);
                fr_assert(mod->rhs != NULL);
 
-               fr_assert(tmpl_is_attr(mod->lhs) || tmpl_is_list(mod->lhs));
+               fr_assert(tmpl_is_attr(mod->lhs));
                fr_assert(((mod->op == T_OP_CMP_FALSE) && tmpl_is_null(mod->rhs)) ||
                           tmpl_is_data(mod->rhs));
 
index f55fbc4bde734da4e55fd96e94fa982d2724f3be..3d636ce15f3ccdab09241f1fb48a2df9b0b3c80e 100644 (file)
@@ -678,8 +678,7 @@ static inline tmpl_type_t tmpl_type_from_str(char const *type)
 static inline FR_DLIST_HEAD(tmpl_request_list) const *tmpl_request(tmpl_t const *vpt)
 {
        tmpl_assert_type(tmpl_is_attr(vpt) ||
-                        tmpl_is_attr_unresolved(vpt) ||
-                        tmpl_is_list(vpt));
+                        tmpl_is_attr_unresolved(vpt));
 
        return &vpt->data.attribute.rr;
 }
@@ -690,8 +689,7 @@ static inline FR_DLIST_HEAD(tmpl_request_list) const *tmpl_request(tmpl_t const
 static inline size_t tmpl_request_ref_count(tmpl_t const *vpt)
 {
        tmpl_assert_type(tmpl_is_attr(vpt) ||
-                        tmpl_is_attr_unresolved(vpt) ||
-                        tmpl_is_list(vpt));
+                        tmpl_is_attr_unresolved(vpt));
 
        return tmpl_request_list_num_elements(&vpt->data.attribute.rr);
 }
@@ -892,10 +890,7 @@ static inline char const *tmpl_attr_tail_unresolved(tmpl_t const *vpt)
 static inline int16_t tmpl_attr_tail_num(tmpl_t const *vpt)
 {
        tmpl_assert_type(tmpl_is_attr(vpt) ||
-                        tmpl_is_attr_unresolved(vpt) ||
-                        tmpl_is_list(vpt));
-
-       if (tmpl_is_list(vpt) && (tmpl_attr_list_num_elements(tmpl_attr(vpt)) == 0)) return NUM_ALL;
+                        tmpl_is_attr_unresolved(vpt));
 
        return tmpl_attr_list_tail(tmpl_attr(vpt))->ar_num;
 }
@@ -914,8 +909,7 @@ static inline size_t tmpl_attr_num_elements(tmpl_t const *vpt)
 static inline fr_dict_attr_t const *tmpl_list(tmpl_t const *vpt)
 {
        tmpl_assert_type(tmpl_is_attr(vpt) ||
-                        tmpl_is_attr_unresolved(vpt) ||                        /* Remove once list is part of ar dlist */
-                        tmpl_is_list(vpt));
+                        tmpl_is_attr_unresolved(vpt));
 
        return vpt->data.attribute.list;
 }
index 3a9cd7fd5898e0abdffd72a59518a0a514298de6..602aabe710067266087d304bc34d0c561331258d 100644 (file)
@@ -104,7 +104,7 @@ void _tmpl_cursor_pair_init(TALLOC_CTX *list_ctx, fr_pair_list_t *list, tmpl_att
        /*
         *      Iterates over attributes of a specific type
         */
-       if (tmpl_is_list(cc->vpt) || ar_is_normal(ar)) {
+       if (ar_is_normal(ar)) {
                fr_pair_dcursor_iter_init(&ns->cursor, list, _tmpl_cursor_child_next, ns);
        /*
         *      Iterates over all attributes at this level
@@ -177,7 +177,7 @@ fr_pair_t *_tmpl_cursor_eval(fr_pair_t *curr, tmpl_dcursor_ctx_t *cc)
                pop = true;
        }
                break;
-       } else goto all_inst;   /* Used for TMPL_TYPE_LIST */
+       } else goto all_inst;
 
        /*
         *      If no pair was found and there is a fill
@@ -411,7 +411,7 @@ fr_pair_t *_tmpl_dcursor_init(int *err, TALLOC_CTX *ctx, tmpl_dcursor_ctx_t *cc,
 {
        fr_pair_t               *list;
 
-       fr_assert(tmpl_is_attr(vpt) || tmpl_is_list(vpt));
+       fr_assert(tmpl_is_attr(vpt));
 
        if (err) *err = 0;
 
@@ -536,7 +536,7 @@ int tmpl_extents_find(TALLOC_CTX *ctx,
 
        TMPL_VERIFY(vpt);
 
-       fr_assert(tmpl_is_attr(vpt) || tmpl_is_list(vpt));
+       fr_assert(tmpl_is_attr(vpt));
 
        /*
         *      Navigate to the correct request context
index e8d94ca29b404b28badd19f2ad5c0ae677651fef..b2eb7b0e2f2715835c229de471d68a63851186b9 100644 (file)
@@ -362,7 +362,6 @@ ssize_t _tmpl_to_type(void *out,
 
        TMPL_VERIFY(vpt);
 
-       fr_assert(!tmpl_is_list(vpt));
        fr_assert(!buff || (bufflen >= 2));
 
        switch (vpt->type) {
@@ -868,7 +867,7 @@ int tmpl_copy_pairs(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, tm
 
        TMPL_VERIFY(vpt);
 
-       fr_assert(tmpl_is_attr(vpt) || tmpl_is_list(vpt));
+       fr_assert(tmpl_is_attr(vpt));
 
        for (vp = tmpl_dcursor_init(&err, NULL, &cc, &from, request, vpt);
             vp;
@@ -912,7 +911,7 @@ int tmpl_copy_pair_children(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *req
 
        TMPL_VERIFY(vpt);
 
-       fr_assert(tmpl_is_attr(vpt) || tmpl_is_list(vpt));
+       fr_assert(tmpl_is_attr(vpt));
 
        fr_pair_list_free(out);
 
@@ -1297,7 +1296,7 @@ int tmpl_eval_pair(TALLOC_CTX *ctx, FR_DLIST_HEAD(fr_value_box_list) *out, reque
        int                     ret = 0;
        FR_DLIST_HEAD(fr_value_box_list)        list;
 
-       fr_assert(tmpl_is_attr(vpt) || tmpl_is_list(vpt));
+       fr_assert(tmpl_is_attr(vpt));
 
        fr_value_box_list_init(&list);
 
@@ -1452,7 +1451,7 @@ int tmpl_eval(TALLOC_CTX *ctx, FR_DLIST_HEAD(fr_value_box_list) *out, request_t
                return -1;
        }
 
-       if (tmpl_is_attr(vpt) || tmpl_is_list(vpt)) {
+       if (tmpl_is_attr(vpt)) {
                return tmpl_eval_pair(ctx, out, request, vpt);
        }
 
index 9e427c6ad8e1ae9e4c518b86925997e0e030c681..4df7820c7b668497f5a546f79154d1fd4c293573 100644 (file)
@@ -1193,7 +1193,7 @@ void tmpl_attr_set_leaf_num(tmpl_t *vpt, int16_t num)
 {
        tmpl_attr_t *ar;
 
-       tmpl_assert_type(tmpl_is_attr(vpt) || tmpl_is_list(vpt) || tmpl_is_attr_unresolved(vpt));
+       tmpl_assert_type(tmpl_is_attr(vpt) || tmpl_is_attr_unresolved(vpt));
 
        if (tmpl_attr_list_num_elements(tmpl_attr(vpt)) == 0) {
                ar = tmpl_attr_add(vpt, TMPL_ATTR_TYPE_UNKNOWN);
@@ -1213,7 +1213,7 @@ void tmpl_attr_rewrite_leaf_num(tmpl_t *vpt, int16_t from, int16_t to)
 {
        tmpl_attr_t *ref = NULL;
 
-       tmpl_assert_type(tmpl_is_attr(vpt) || tmpl_is_list(vpt) || tmpl_is_attr_unresolved(vpt));
+       tmpl_assert_type(tmpl_is_attr(vpt) || tmpl_is_attr_unresolved(vpt));
 
        if (tmpl_attr_list_num_elements(tmpl_attr(vpt)) == 0) return;
 
@@ -1230,7 +1230,7 @@ void tmpl_attr_rewrite_num(tmpl_t *vpt, int16_t from, int16_t to)
 {
        tmpl_attr_t *ref = NULL;
 
-       tmpl_assert_type(tmpl_is_attr(vpt) || tmpl_is_list(vpt) || tmpl_is_attr_unresolved(vpt));
+       tmpl_assert_type(tmpl_is_attr(vpt) || tmpl_is_attr_unresolved(vpt));
 
        while ((ref = tmpl_attr_list_next(tmpl_attr(vpt), ref))) if (ref->ar_num == from) ref->ar_num = to;
 
@@ -4412,7 +4412,7 @@ fr_slen_t tmpl_attr_print(fr_sbuff_t *out, tmpl_t const *vpt, tmpl_attr_prefix_t
         */
        ar = NULL;
        while ((ar = tmpl_attr_list_next(tmpl_attr(vpt), ar))) {
-               if (!tmpl_is_list(vpt)) switch(ar->type) {
+               switch(ar->type) {
                case TMPL_ATTR_TYPE_UNSPEC:
                        break;
 
@@ -4720,7 +4720,7 @@ void tmpl_attr_verify(char const *file, int line, tmpl_t const *vpt)
        tmpl_attr_t     *seen_unknown = NULL;
        tmpl_attr_t     *seen_unresolved = NULL;
 
-       fr_assert(tmpl_is_attr_unresolved(vpt) || tmpl_is_attr(vpt) || tmpl_is_list(vpt));
+       fr_assert(tmpl_is_attr_unresolved(vpt) || tmpl_is_attr(vpt));
 
        /*
         *      Loop detection
index c029e2edf5990e1758cbad2f6b708c5b607d8eae..3c1977f15b983cfc9707f33dfa3bc9d98ae1440e 100644 (file)
@@ -919,75 +919,6 @@ int unlang_fixup_update(map_t *map, void *ctx)
                }
        }
 
-       if (tmpl_is_list(map->lhs)) {
-               /*
-                *      Can't copy an xlat expansion or literal into a list,
-                *      we don't know what type of attribute we'd need
-                *      to create.
-                *
-                *      The only exception is where were using a unary
-                *      operator like !*.
-                */
-               if (map->op != T_OP_CMP_FALSE) switch (map->rhs->type) {
-               case TMPL_TYPE_XLAT_UNRESOLVED:
-               case TMPL_TYPE_UNRESOLVED:
-                       cf_log_err(map->ci, "Can't copy value into list (we don't know which attribute to create)");
-                       return -1;
-
-               default:
-                       break;
-               }
-
-               /*
-                *      Only += and :=, and !*, and ^= operators are supported
-                *      for lists.
-                */
-               switch (map->op) {
-               case T_OP_CMP_FALSE:
-                       break;
-
-               case T_OP_ADD_EQ:
-                       if (!tmpl_is_list(map->rhs) &&
-                           !tmpl_is_exec(map->rhs)) {
-                               cf_log_err(map->ci, "Invalid source for list assignment '%s += ...'", map->lhs->name);
-                               return -1;
-                       }
-                       break;
-
-               case T_OP_SET:
-                       if (tmpl_is_exec(map->rhs)) {
-                               WARN("%s[%d]: Please change ':=' to '=' for list assignment",
-                                    cf_filename(cp), cf_lineno(cp));
-                       }
-
-                       if (!tmpl_is_list(map->rhs)) {
-                               cf_log_err(map->ci, "Invalid source for list assignment '%s := ...'", map->lhs->name);
-                               return -1;
-                       }
-                       break;
-
-               case T_OP_EQ:
-                       if (!tmpl_is_exec(map->rhs)) {
-                               cf_log_err(map->ci, "Invalid source for list assignment '%s = ...'", map->lhs->name);
-                               return -1;
-                       }
-                       break;
-
-               case T_OP_PREPEND:
-                       if (!tmpl_is_list(map->rhs) &&
-                           !tmpl_is_exec(map->rhs)) {
-                               cf_log_err(map->ci, "Invalid source for list assignment '%s ^= ...'", map->lhs->name);
-                               return -1;
-                       }
-                       break;
-
-               default:
-                       cf_log_err(map->ci, "Operator \"%s\" not allowed for list assignment",
-                                  fr_table_str_by_value(fr_tokens_table, map->op, "<INVALID>"));
-                       return -1;
-               }
-       }
-
        /*
         *      If the map has a unary operator there's no further
         *      processing we need to, as RHS is unused.
@@ -3527,7 +3458,7 @@ static unlang_t *compile_foreach(unlang_t *parent, unlang_compile_t *unlang_ctx,
         */
        fr_assert(vpt);
 
-       if (!tmpl_is_attr(vpt) && !tmpl_is_list(vpt)) {
+       if (!tmpl_is_attr(vpt)) {
                cf_log_err(cs, "MUST use attribute or list reference (not %s) in 'foreach'",
                           tmpl_type_to_str(vpt->type));
                talloc_free(vpt);
index 9075708a07aa2002b6244dd263dadda47ac96d53..074b3f637880c95447351bb0a7b0615057e59474 100644 (file)
@@ -203,18 +203,9 @@ static unlang_action_t unlang_subrequest_parent_init(rlm_rcode_t *p_result, requ
        }
        fr_pair_append(&child->request_pairs, vp);
 
-       if (gext->src) {
-               if (tmpl_is_list(gext->src)) {
-                       if (tmpl_copy_pairs(child->request_ctx, &child->request_pairs, request, gext->src) < -1) {
-                               RPEDEBUG("Failed copying source attributes into subrequest");
-                               goto fail;
-                       }
-               } else {
-                       if (tmpl_copy_pair_children(child->request_ctx, &child->request_pairs, request, gext->src) < -1) {
-                               RPEDEBUG("Failed copying source attributes into subrequest");
-                               goto fail;
-                       }
-               }
+       if ((gext->src) && (tmpl_copy_pair_children(child->request_ctx, &child->request_pairs, request, gext->src) < -1)) {
+               RPEDEBUG("Failed copying source attributes into subrequest");
+               goto fail;
        }
 
        /*
index ea98acde399ab10879cf0a55fd11d902e3e83798..11370154b8fd60c53fde3dda9983f3432f7e18b2 100644 (file)
@@ -1149,7 +1149,7 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_head_
                                fr_value_box_list_move((FR_DLIST_HEAD(fr_value_box_list) *)out->dlist, &result);
                                continue;
 
-                       } else if (tmpl_is_attr(node->vpt) ||  tmpl_is_list(node->vpt)) {
+                       } else if (tmpl_is_attr(node->vpt)) {
                                if (node->fmt[0] == '&') {
                                        XLAT_DEBUG("** [%i] %s(attribute) - %s", unlang_interpret_stack_depth(request), __FUNCTION__,
                                                   node->fmt);
index 6f3adc818ed814b2792c35d182b43c39aae92cb3..70525c5d9bb0d6c859f3f1c174db4d27e9cf05d1 100644 (file)
@@ -1273,7 +1273,7 @@ ssize_t xlat_print_node(fr_sbuff_t *out, xlat_exp_head_t const *head, xlat_exp_t
                fr_assert(!tmpl_contains_regex(node->vpt));
 
                // attr or list
-               fr_assert(tmpl_is_list(node->vpt) || tmpl_is_attr(node->vpt));
+               fr_assert(tmpl_is_attr(node->vpt));
                fr_assert(talloc_parent(node->vpt) == node);
                fr_assert(!node->flags.pure);
 
index 65737fe623bf89f8afbb475d8af57f109c62dd82..3b8e78781099b854fbaa6ddd5d105d3c5ac3b0bf 100644 (file)
@@ -531,8 +531,7 @@ static int cache_verify(map_t *map, void *ctx)
 {
        if (unlang_fixup_update(map, ctx) < 0) return -1;
 
-       if (!tmpl_is_attr(map->lhs) &&
-           !tmpl_is_list(map->lhs)) {
+       if (!tmpl_is_attr(map->lhs)) {
                cf_log_err(map->ci, "Destination must be an attribute ref or a list");
                return -1;
        }
index c5835649fd5700e5287ebea373e66c79f1f994db..a4d48ddc9678ca81e1aba2fe1aef90c5d3fce4d9 100644 (file)
@@ -159,11 +159,6 @@ static int cf_table_parse_tmpl(TALLOC_CTX *ctx, void *out, UNUSED void *parent,
                goto finish;
        }
 
-       if(tmpl_is_list(vpt)) {
-               ret = -1;
-               goto finish;
-       }
-
        /* Only string values should be used for SMTP components */
        if(tmpl_expanded_type(vpt) != FR_TYPE_STRING) {
                cf_log_err(cp, "Attribute reference must be a string");