From: Alan T. DeKok Date: Sat, 13 Aug 2022 13:50:08 +0000 (-0400) Subject: create fr_pair_list_foreach() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5740e114e83fb7dc46afb232d039476afdced049;p=thirdparty%2Ffreeradius-server.git create fr_pair_list_foreach() which is also safe to use when deleting the iteration variable --- diff --git a/src/lib/server/client.c b/src/lib/server/client.c index a2a24752a8a..98b22922727 100644 --- a/src/lib/server/client.c +++ b/src/lib/server/client.c @@ -947,7 +947,6 @@ RADCLIENT *client_afrom_request(TALLOC_CTX *ctx, request_t *request) static int cnt; CONF_SECTION *cs; char src_buf[128], buffer[256]; - fr_pair_t *vp; RADCLIENT *c; if (!request) return NULL; @@ -961,9 +960,7 @@ RADCLIENT *client_afrom_request(TALLOC_CTX *ctx, request_t *request) RDEBUG2("Converting &request.control to client {...} section"); RINDENT(); - for (vp = fr_pair_list_head(&request->control_pairs); - vp != NULL; - vp = fr_pair_list_next(&request->control_pairs, vp)) { + fr_pair_list_foreach(&request->control_pairs, vp) { CONF_PAIR *cp = NULL; char const *value; char const *attr; diff --git a/src/lib/server/log.c b/src/lib/server/log.c index 305f2a40f64..29cb0474444 100644 --- a/src/lib/server/log.c +++ b/src/lib/server/log.c @@ -806,17 +806,12 @@ void log_request_pair(fr_log_lvl_t lvl, request_t *request, void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix) { - fr_pair_list_t *m_vp = UNCONST(fr_pair_list_t *, vps); - fr_pair_t *vp; - if (fr_pair_list_empty(vps) || !request->log.dst) return; if (!log_rdebug_enabled(lvl, request)) return; RINDENT(); - for (vp = fr_pair_list_head(m_vp); - vp; - vp = fr_pair_list_next(m_vp, vp)) { + fr_pair_list_foreach(vps, vp) { PAIR_VERIFY(vp); log_request_pair(lvl, request, parent, vp, prefix); @@ -835,16 +830,12 @@ void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, void log_request_proto_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix) { - fr_pair_t *vp; - if (fr_pair_list_empty(vps) || !request->log.dst) return; if (!log_rdebug_enabled(lvl, request)) return; RINDENT(); - for (vp = fr_pair_list_head(vps); - vp; - vp = fr_pair_list_next(vps, vp)) { + fr_pair_list_foreach(vps, vp) { PAIR_VERIFY(vp); if (!fr_dict_attr_common_parent(fr_dict_root(request->dict), vp->da, true)) continue; diff --git a/src/lib/server/map.c b/src/lib/server/map.c index 2ac2857ad2f..7496693083f 100644 --- a/src/lib/server/map.c +++ b/src/lib/server/map.c @@ -1375,7 +1375,7 @@ static int map_exec_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *reque int map_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, map_t const *map, UNUSED void *uctx) { int rcode = 0; - fr_pair_t *vp, *n = NULL; + fr_pair_t *n = NULL; fr_pair_list_t found; request_t *context = request; ssize_t slen; @@ -1472,9 +1472,7 @@ int map_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, map_t co */ if (fr_pair_list_empty(&found)) return 0; - for (vp = fr_pair_list_head(&found); - vp; - vp = fr_pair_list_next(&found, vp)) { + fr_pair_list_foreach(&found, vp) { vp->op = T_OP_ADD_EQ; } @@ -1539,6 +1537,7 @@ int map_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, map_t co case TMPL_TYPE_ATTR: { + fr_pair_t *vp; fr_dcursor_t from; fr_assert((tmpl_is_attr(map->lhs) && tmpl_da(map->lhs)) || @@ -1670,7 +1669,7 @@ do {\ int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t func, void *ctx) { int rcode = 0; - fr_pair_t *vp, *dst; + fr_pair_t *dst; fr_pair_list_t *list, src_list; request_t *context, *tmp_ctx = NULL; TALLOC_CTX *parent; @@ -1810,9 +1809,7 @@ int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t f if (RDEBUG_ENABLED) #endif { - for (vp = fr_pair_list_head(&src_list); - vp; - vp = fr_pair_list_next(&src_list, vp)) { + fr_pair_list_foreach(&src_list, vp) { PAIR_VERIFY(vp); if (RDEBUG_ENABLED) map_debug_log(request, map, vp); @@ -1924,9 +1921,7 @@ int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t f * Instance specific[n] delete */ if (tmpl_num(map->lhs) != NUM_UNSPEC) { - for (vp = fr_pair_list_head(&src_list); - vp; - vp = fr_pair_list_next(&src_list, vp)) { + fr_pair_list_foreach(&src_list, vp) { vp->op = T_OP_CMP_EQ; rcode = paircmp_pairs(request, vp, dst); if (rcode == 0) { @@ -1947,9 +1942,7 @@ int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t f for (dst = fr_dcursor_current(&dst_list); dst; dst = fr_dcursor_filter_next(&dst_list, fr_pair_matches_da, tmpl_da(map->lhs))) { - for (vp = fr_pair_list_head(&src_list); - vp; - vp = fr_pair_list_next(&src_list, vp)) { + fr_pair_list_foreach(&src_list, vp) { vp->op = T_OP_CMP_EQ; rcode = paircmp_pairs(request, vp, dst); if (rcode == 0) { @@ -2138,16 +2131,14 @@ int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t f case T_OP_LE: case T_OP_LT: { - fr_pair_t *a, *b; + fr_pair_t *a; fr_pair_list_sort(&src_list, fr_pair_cmp_by_da); fr_pair_list_sort(list, fr_pair_cmp_by_da); fr_dcursor_head(&dst_list); - for (b = fr_pair_list_head(&src_list); - b; - b = fr_pair_list_next(&src_list, b)) { + fr_pair_list_foreach(&src_list, b) { for (a = fr_dcursor_current(&dst_list); a; a = fr_dcursor_next(&dst_list)) { diff --git a/src/lib/server/map_async.c b/src/lib/server/map_async.c index 64a35759b83..b10b8fe0b6a 100644 --- a/src/lib/server/map_async.c +++ b/src/lib/server/map_async.c @@ -1023,7 +1023,7 @@ int map_list_mod_apply(request_t *request, vp_list_mod_t const *vlm) { bool exists = false; fr_pair_list_t vp_from, vp_to_insert; - fr_pair_t *vp, *vp_to = NULL; + fr_pair_t *vp; fr_pair_list_init(&vp_from); fr_pair_list_init(&vp_to_insert); @@ -1031,9 +1031,7 @@ int map_list_mod_apply(request_t *request, vp_list_mod_t const *vlm) if (fr_pair_list_empty(&vp_from)) goto finish; while ((vp = fr_pair_remove(&vp_from, fr_pair_list_head(&vp_from)))) { - for (vp_to = fr_pair_list_head(vp_list); - vp_to; - vp_to = fr_pair_list_head(vp_list)) { + fr_pair_list_foreach(vp_list, vp_to) { if (fr_pair_cmp_by_da(vp_to, vp) == 0) { exists = true; break; diff --git a/src/lib/server/paircmp.c b/src/lib/server/paircmp.c index 35905499bd1..82933957060 100644 --- a/src/lib/server/paircmp.c +++ b/src/lib/server/paircmp.c @@ -502,7 +502,6 @@ int paircmp(request_t *request, fr_pair_list_t *request_list, fr_pair_list_t *check_list) { - fr_pair_t *check_item; fr_pair_t *auth_item; fr_dict_attr_t const *from; @@ -510,9 +509,7 @@ int paircmp(request_t *request, int compare; bool first_only; - for (check_item = fr_pair_list_head(check_list); - check_item; - check_item = fr_pair_list_next(check_list, check_item)) { + fr_pair_list_foreach(check_list, check_item) { /* * If the user is setting a configuration value, * then don't bother comparing it to any attributes diff --git a/src/lib/unlang/edit.c b/src/lib/unlang/edit.c index 43adc4db953..f33e5d7ce8f 100644 --- a/src/lib/unlang/edit.c +++ b/src/lib/unlang/edit.c @@ -471,12 +471,10 @@ static int apply_edits_to_leaf(request_t *request, edit_map_t *current, map_t co if (fr_pair_list_empty(¤t->rhs.pair_list)) return 0; - for (vp = fr_pair_list_head(¤t->rhs.pair_list); - vp != NULL; - vp = fr_pair_list_next(¤t->rhs.pair_list, vp)) { - (void) talloc_steal(current->lhs.vp_parent, vp); + fr_pair_list_foreach(¤t->rhs.pair_list, child) { + (void) talloc_steal(current->lhs.vp_parent, child); - RDEBUG2("%s %s %pV", current->lhs.vpt->name, fr_tokens[map->op], &vp->data); + RDEBUG2("%s %s %pV", current->lhs.vpt->name, fr_tokens[map->op], &child->data); } if (fr_edit_list_insert_list_tail(current->el, ¤t->lhs.vp_parent->vp_group, diff --git a/src/lib/util/edit.c b/src/lib/util/edit.c index 4a7e50e6f9d..70b0d30ba16 100644 --- a/src/lib/util/edit.c +++ b/src/lib/util/edit.c @@ -525,8 +525,6 @@ int fr_edit_list_pair_delete(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t */ int fr_edit_list_pair_delete_by_da(fr_edit_list_t *el, fr_pair_list_t *list, fr_dict_attr_t const *da) { - fr_pair_t *vp, *next; - if (!el) { fr_pair_delete_by_da(list, da); return 0; @@ -535,10 +533,7 @@ int fr_edit_list_pair_delete_by_da(fr_edit_list_t *el, fr_pair_list_t *list, fr_ /* * Delete all VPs with a matching da. */ - for (vp = fr_pair_list_head(list); - vp != NULL; - vp = next) { - next = fr_pair_list_next(list, vp); + fr_pair_list_foreach(list, vp) { if (vp->da != da) continue; (void) fr_pair_remove(list, vp); @@ -800,11 +795,7 @@ int fr_edit_list_insert_list_after(fr_edit_list_t *el, fr_pair_list_t *list, fr_ */ static int fr_edit_list_delete_list(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_list_t *to_remove) { - fr_pair_t *vp; - - for (vp = fr_pair_list_head(to_remove); - vp != NULL; - vp = fr_pair_list_next(to_remove, vp)) { + fr_pair_list_foreach(to_remove, vp) { fr_pair_t *found, *next; /* diff --git a/src/lib/util/pair.c b/src/lib/util/pair.c index cfb46339315..d4a635ac480 100644 --- a/src/lib/util/pair.c +++ b/src/lib/util/pair.c @@ -1386,11 +1386,9 @@ int fr_pair_update_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, */ int fr_pair_delete_by_da(fr_pair_list_t *list, fr_dict_attr_t const *da) { - fr_pair_t *vp, *next; int cnt = 0; - for (vp = fr_pair_list_head(list); vp; vp = next) { - next = fr_pair_list_next(list, vp); + fr_pair_list_foreach(list, vp) { if (da == vp->da) { cnt++; fr_pair_delete(list, vp); @@ -1786,7 +1784,7 @@ mismatch: */ bool fr_pair_validate_relaxed(fr_pair_t const *failed[2], fr_pair_list_t *filter, fr_pair_list_t *list) { - fr_pair_t *check, *last_check = NULL, *match = NULL; + fr_pair_t *last_check = NULL, *match = NULL; if (fr_pair_list_empty(filter) && fr_pair_list_empty(list)) return true; @@ -1799,9 +1797,7 @@ bool fr_pair_validate_relaxed(fr_pair_t const *failed[2], fr_pair_list_t *filter fr_pair_list_sort(filter, fr_pair_cmp_by_da); fr_pair_list_sort(list, fr_pair_cmp_by_da); - for (check = fr_pair_list_head(filter); - check; - check = fr_pair_list_next(filter, check)) { + fr_pair_list_foreach(filter, check) { /* * Were processing check attributes of a new type. */ @@ -1838,20 +1834,20 @@ bool fr_pair_validate_relaxed(fr_pair_t const *failed[2], fr_pair_list_t *filter /* * This attribute passed the filter */ - if (!fr_pair_cmp(check, match)) goto mismatch; + if (!fr_pair_cmp(check, match)) { + mismatch: + if (failed) { + failed[0] = check; + failed[1] = match; + } + return false; + } break; } } } return true; - -mismatch: - if (failed) { - failed[0] = check; - failed[1] = match; - } - return false; } /** Steal a list of pairs to a new context @@ -1859,11 +1855,7 @@ mismatch: */ void fr_pair_list_steal(TALLOC_CTX *ctx, fr_pair_list_t *list) { - fr_pair_t *vp; - - for (vp = fr_pair_list_head(list); - vp; - vp = fr_pair_list_next(list, vp)) { + fr_pair_list_foreach(list, vp) { (void) fr_pair_steal(ctx, vp); } } @@ -1882,12 +1874,11 @@ void fr_pair_list_steal(TALLOC_CTX *ctx, fr_pair_list_t *list) */ int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from) { - fr_pair_t *vp, *new_vp, *first_added = NULL; + fr_pair_t *new_vp, *first_added = NULL; int cnt = 0; - for (vp = fr_pair_list_head(from); - vp; - vp = fr_pair_list_next(from, vp), cnt++) { + fr_pair_list_foreach(from, vp) { + cnt++; PAIR_VERIFY_WITH_LIST(from, vp); new_vp = fr_pair_copy(ctx, vp); @@ -1920,13 +1911,11 @@ int fr_pair_list_copy_to_box(fr_value_box_t *dst, fr_pair_list_t *from) { int cnt = 0; fr_value_box_t *value, *first_added = NULL; - fr_pair_t *vp; fr_assert(dst->type == FR_TYPE_GROUP); - for (vp = fr_pair_list_head(from); - vp; - vp = fr_pair_list_next(from, vp), cnt++) { + fr_pair_list_foreach(from, vp) { + cnt++; PAIR_VERIFY_WITH_LIST(from, vp); if (fr_type_is_structural(vp->da->type)) { @@ -2838,11 +2827,7 @@ void fr_pair_verify(char const *file, int line, fr_pair_list_t const *list, fr_p case FR_TYPE_STRUCTURAL: { - fr_pair_t *child; - - for (child = fr_pair_list_head(&vp->vp_group); - child; - child = fr_pair_list_next(&vp->vp_group, child)) { + fr_pair_list_foreach(&vp->vp_group, child) { TALLOC_CTX *parent = talloc_parent(child); fr_fatal_assert_msg(parent == vp, @@ -2960,13 +2945,9 @@ void fr_pair_list_verify(char const *file, int line, TALLOC_CTX const *expected, */ void fr_pair_list_tainted(fr_pair_list_t *list) { - fr_pair_t *vp; - if (fr_pair_list_empty(list)) return; - for (vp = fr_pair_list_head(list); - vp; - vp = fr_pair_list_next(list, vp)) { + fr_pair_list_foreach(list, vp) { PAIR_VERIFY_WITH_LIST(list, vp); switch (vp->da->type) { @@ -3082,11 +3063,7 @@ static const char spaces[] = " static void fprintf_pair_list(FILE *fp, fr_pair_list_t const *list, int depth) { - fr_pair_t *vp; - - for (vp = fr_pair_list_head(list); - vp != NULL; - vp = fr_pair_list_next(list, vp)) { + fr_pair_list_foreach(list, vp) { fprintf(fp, "%.*s", depth, spaces); if (fr_type_is_leaf(vp->da->type)) { diff --git a/src/lib/util/pair.h b/src/lib/util/pair.h index 398609c65a8..02693470b06 100644 --- a/src/lib/util/pair.h +++ b/src/lib/util/pair.h @@ -213,6 +213,17 @@ static inline bool vp_da_data_type_check(fr_pair_t *vp) return false; } +/** Iterate over the contents of a #pair_list_t + * + * The iteration variable can be safely removed from the list at each pass. + * + * @param[in] _list_head to iterate over. + * @param[in] _iter Name of iteration variable. + * Will be declared in the scope of the loop. + */ +#define fr_pair_list_foreach(_list_head, _iter) \ + for (fr_pair_t *_next, *_iter = fr_pair_list_head(_list_head); _next = fr_pair_list_next(_list_head, _iter), _iter != NULL; _iter = _next) + /** Append a pair to a list, assigning its value. * * Version for simple C data types diff --git a/src/lib/util/pair_print.c b/src/lib/util/pair_print.c index 51888eb1081..8e1f175c5e7 100644 --- a/src/lib/util/pair_print.c +++ b/src/lib/util/pair_print.c @@ -143,11 +143,10 @@ void fr_pair_fprint(FILE *fp, fr_pair_t const *vp) static void fr_pair_list_log_sbuff(fr_log_t const *log, int lvl, fr_pair_t *parent, fr_pair_list_t const *list, char const *file, int line, fr_sbuff_t *sbuff) { - fr_pair_t *vp; fr_dict_attr_t const *parent_da = NULL; - for (vp = fr_pair_list_head(list); vp; vp = fr_pair_list_next(list, vp)) { - PAIR_VERIFY(vp); + fr_pair_list_foreach(list, vp) { + PAIR_VERIFY_WITH_LIST(list, vp); fr_sbuff_set_to_start(sbuff); diff --git a/src/modules/rlm_detail/rlm_detail.c b/src/modules/rlm_detail/rlm_detail.c index 3b93a97051e..e3af857c200 100644 --- a/src/modules/rlm_detail/rlm_detail.c +++ b/src/modules/rlm_detail/rlm_detail.c @@ -234,7 +234,6 @@ static void detail_fr_pair_fprint(TALLOC_CTX *ctx, FILE *out, fr_pair_t const *s static int detail_write(FILE *out, rlm_detail_t const *inst, request_t *request, fr_radius_packet_t *packet, fr_pair_list_t *list, bool compat) { - fr_pair_t *vp; char timestamp[256]; char *header; @@ -317,20 +316,16 @@ static int detail_write(FILE *out, rlm_detail_t const *inst, request_t *request, detail_fr_pair_fprint(request, out, &dst_vp); } - { - /* Write each attribute/value to the log file */ - for (vp = fr_pair_list_head(list); - vp; - vp = fr_pair_list_next(list, vp)) { - if (inst->ht && fr_hash_table_find(inst->ht, vp->da)) continue; + /* Write each attribute/value to the log file */ + fr_pair_list_foreach(list, vp) { + if (inst->ht && fr_hash_table_find(inst->ht, vp->da)) continue; - /* - * Don't print passwords in old format... - */ - if (compat && (vp->da == attr_user_password)) continue; + /* + * Don't print passwords in old format... + */ + if (compat && (vp->da == attr_user_password)) continue; - fr_pair_fprint(out, vp); - } + fr_pair_fprint(out, vp); } /* diff --git a/src/modules/rlm_utf8/rlm_utf8.c b/src/modules/rlm_utf8/rlm_utf8.c index c68c6b1037f..9444bcc944d 100644 --- a/src/modules/rlm_utf8/rlm_utf8.c +++ b/src/modules/rlm_utf8/rlm_utf8.c @@ -32,11 +32,8 @@ RCSID("$Id$") static unlang_action_t CC_HINT(nonnull) mod_utf8_clean(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request) { size_t i, len; - fr_pair_t *vp; - for (vp = fr_pair_list_head(&request->request_pairs); - vp; - vp = fr_pair_list_next(&request->request_pairs, vp)) { + fr_pair_list_foreach(&request->request_pairs, vp) { if (vp->vp_type != FR_TYPE_STRING) continue; for (i = 0; i < vp->vp_length; i += len) {