The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
pair.h
Go to the documentation of this file.
1 #pragma once
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16  */
17 
18 /** AVP manipulation and search API
19  *
20  * @file src/lib/util/pair.h
21  *
22  * @copyright 2020 The FreeRADIUS server project
23  */
24 RCSIDH(dpair_h, "$Id: 0a9e98d212b120b5d4dff46598c298d100b99a83 $")
25 
26 #include <freeradius-devel/build.h>
27 #include <freeradius-devel/missing.h>
28 #include <freeradius-devel/util/dcursor.h>
29 #include <freeradius-devel/util/value.h>
30 #include <freeradius-devel/util/tlist.h>
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 /*
37  * Allow public and private versions of the same structures
38  */
39 #ifdef _CONST
40 # error _CONST can only be defined in the local header
41 #endif
42 #ifndef _PAIR_PRIVATE
43 # define _CONST const
44 #else
45 # define _CONST
46 #endif
47 
48 typedef struct value_pair_s fr_pair_t;
49 
50 FR_TLIST_TYPES(fr_pair_order_list)
51 
52 typedef struct pair_list_s {
53  FR_TLIST_HEAD(fr_pair_order_list) order; //!< Maintains the relative order of pairs in a list.
54 
55  bool _CONST is_child; //!< is a child of a VP
56 
57 #ifdef WITH_VERIFY_PTR
58  unsigned int verified : 1; //!< hack to avoid O(N^3) issues
59 #endif
61 
62 /** Stores an attribute, a value and various bits of other data
63  *
64  * fr_pair_ts are the main data structure used in the server
65  *
66  * They also specify what behaviour should be used when the attribute is merged into a new list/tree.
67  */
68 struct value_pair_s {
69  fr_dict_attr_t const * _CONST da; //!< Dictionary attribute defines the attribute
70  //!< number, vendor and type of the pair.
71  ///< Note: This should not be modified outside
72  ///< of pair.c except via #fr_pair_reinit_from_da.
73 
74  FR_TLIST_ENTRY(fr_pair_order_list) _CONST order_entry; //!< Entry to maintain relative order within a list
75  ///< of pairs. This ensures pairs within the list
76  ///< are encoded in the same order as they were
77  ///< received or inserted.
78 
79 
80  /*
81  * Pairs can have children or data but not both.
82  */
83  union {
84  fr_value_box_t data; //!< The value of this pair.
85 
86  struct {
87  /** Force children field to come _after_ the type field in the fr_value_box_t
88  *
89  * This works no matter where type appears in fr_value_box_t, whereas just
90  * listing another fr_type_t field here does not.
91  *
92  * This hack allows the majority of the fr_pair_list_t to overlap with the
93  * fr_value_box_t which gives us much greater packing efficiency.
94  */
95  uint8_t pad[offsetof(fr_value_box_t, type) + sizeof(fr_type_t)];
96 
97  fr_pair_list_t children; //!< Nested attributes of this pair.
98  };
99  };
100 
101  /*
102  * Legacy stuff that needs to die.
103  */
104  struct {
105  fr_token_t op; //!< Operator to use when moving or inserting
106  };
107 };
108 
109 #define vp_strvalue data.vb_strvalue
110 #define vp_octets data.vb_octets
111 #define vp_ptr data.datum.ptr //!< Either octets or strvalue
112 #define vp_length data.vb_length
113 
114 #define vp_ipv4addr data.vb_ip.addr.v4.s_addr
115 #define vp_ipv6addr data.vb_ip.addr.v6.s6_addr
116 #define vp_ip data.vb_ip
117 #define vp_ifid data.vb_ifid
118 #define vp_ether data.vb_ether
119 
120 #define vp_bool data.datum.boolean
121 #define vp_uint8 data.vb_uint8
122 #define vp_uint16 data.vb_uint16
123 #define vp_uint32 data.vb_uint32
124 #define vp_uint64 data.vb_uint64
125 
126 #define vp_int8 data.vb_int8
127 #define vp_int16 data.vb_int16
128 #define vp_int32 data.vb_int32
129 #define vp_int64 data.vb_int64
130 
131 #define vp_float32 data.vb_float32
132 #define vp_float64 data.vb_float64
133 
134 #define vp_date data.vb_date
135 #define vp_time_delta data.vb_time_delta
136 
137 #define vp_group children
138 
139 #define vp_size data.datum.size
140 #define vp_filter data.datum.filter
141 
142 #define vp_type data.type
143 #define vp_tainted data.tainted
144 #define vp_immutable data.immutable
145 #define vp_raw da->flags.is_raw
146 
147 #define ATTRIBUTE_EQ(_x, _y) ((_x && _y) && (_x->da == _y->da))
148 
149 /** If WITH_VERIFY_PTR is defined, we perform runtime checks to ensure the fr_pair_t are sane
150  *
151  */
152 #ifdef WITH_VERIFY_PTR
153 void fr_pair_verify(char const *file, int line, fr_pair_list_t const *list, fr_pair_t const *vp) CC_HINT(nonnull(4));
154 
155 void fr_pair_list_verify(char const *file, int line,
156  TALLOC_CTX const *expected, fr_pair_list_t const *list) CC_HINT(nonnull(4));
157 
158 # define PAIR_VERIFY(_x) fr_pair_verify(__FILE__, __LINE__, NULL, _x)
159 # define PAIR_VERIFY_WITH_LIST(_l, _x) fr_pair_verify(__FILE__, __LINE__, _l, _x)
160 # define PAIR_LIST_VERIFY(_x) fr_pair_list_verify(__FILE__, __LINE__, NULL, _x)
161 #else
162 DIAG_OFF(nonnull-compare)
163 /** Wrapper function to defeat nonnull checks
164  *
165  * We may sprinkle PAIR_VERIFY and PAIR_LIST_VERIFY in functions which
166  * have their pair argument marked up as nonnull.
167  *
168  * This would usually generate errors when WITH_VERIFY_PTR is not
169  * defined, as the assert macros check for an arguments NULLness.
170  *
171  * This function wraps the assert but has nonnull-compare disabled
172  * meaning a warning won't be emitted.
173  */
174 static inline bool fr_pair_nonnull_assert(fr_pair_t const *vp)
175 {
176  return fr_cond_assert(vp);
177 }
178 
180 {
181  return fr_cond_assert(pair_list);
182 }
183 DIAG_ON(nonnull-compare)
184 
185 /*
186  * Even if were building without WITH_VERIFY_PTR
187  * the pointer must not be NULL when these various macros are used
188  * so we can add some sneaky soft asserts.
189  */
190 # define PAIR_VERIFY(_x) fr_pair_nonnull_assert(_x)
191 # define PAIR_VERIFY_WITH_LIST(_l, _x) fr_pair_list_nonnull_assert(_l); \
192  fr_pair_nonnull_assert(_x)
193 # define PAIR_LIST_VERIFY(_x) fr_pair_list_nonnull_assert(_x)
194 #endif
195 
196 
197 #ifdef TEST_CHECK
198 /** Macro for use in acutest tests
199  */
200 #define TEST_CHECK_PAIR(_got, _exp) \
201 do { \
202  fr_pair_t const *_our_got = (_got); \
203  fr_pair_t const *_our_exp = (_exp); \
204  TEST_CHECK_(_our_exp == _our_got, "%s", #_got); \
205  if (_our_exp) { \
206  TEST_MSG("Expected pair : %s - %p (%s)", (_our_exp)->da->name, _our_exp, talloc_get_name(_our_exp)); \
207  } else { \
208  TEST_MSG("Expected pair : NULL"); \
209  } \
210  if (_our_got) { \
211  TEST_MSG("Got pair : %s - %p (%s)", (_our_got)->da->name, _our_got, talloc_get_name(_our_got)); \
212  } else { \
213  TEST_MSG("Got Pair : NULL"); \
214  } \
215 } while(0)
216 
217 #define TEST_CHECK_PAIR_NEQ(_got, _neq) \
218 do { \
219  fr_pair_t const *_our_got = (_got); \
220  fr_pair_t const *_our_neq = (_neq); \
221  TEST_CHECK_(_our_got != _our_neq, "%s", #_got); \
222  if (_our_neq) { \
223  TEST_MSG("Pair must not equal : %s - %p (%s)", (_our_neq)->da->name, _our_neq, talloc_get_name(_our_neq)); \
224  } else { \
225  TEST_MSG("Pair must not equal : NULL"); \
226  } \
227 } while(0)
228 #endif
229 
230 /*
231  * Helper macros for adding pairs to lists and assigning a value to them
232  */
233 
234 /** Check a pair's data type matches the DA data type
235  *
236  * @param[in] vp to check consistency of.
237  * @return
238  * - true for match
239  * - false for error
240  */
241 static inline bool vp_da_data_type_check(fr_pair_t *vp)
242 {
243  if (vp->vp_type == vp->da->type) return true;
244 
245  fr_strerror_printf("fr_pair_t attribute %p \"%s\" data type (%s) does not match da type (%s)",
246  vp->da, vp->da->name,
247  fr_table_str_by_value(fr_type_table, vp->vp_type, "invalid"),
248  fr_table_str_by_value(fr_type_table, vp->da->type, "invalid"));
249  return false;
250 }
251 
252 /** Iterate over the contents of a #fr_pair_list_t
253  *
254  * The iteration variable can be safely removed from the list at each pass.
255  *
256  * @param[in] _list_head to iterate over.
257  * @param[in] _iter Name of iteration variable.
258  * Will be declared in the scope of the loop.
259  */
260 #define fr_pair_list_foreach(_list_head, _iter) \
261  for (fr_pair_t *JOIN(_next,_iter), *_iter = fr_pair_list_head(_list_head); JOIN(_next,_iter) = fr_pair_list_next(_list_head, _iter), _iter != NULL; _iter = JOIN(_next,_iter))
262 
263 /** Iterate over the leaf nodes of a #fr_pair_list_t
264  *
265  * The iteration variable CANNOT be modified. This is a read-only operation.
266  *
267  * @param[in] _list_head to iterate over.
268  * @param[in] _iter Name of iteration variable.
269  * Will be declared in the scope of the loop.
270  */
271 #define fr_pair_list_foreach_leaf(_list_head, _iter) \
272  for (fr_pair_t *_iter = fr_pair_list_iter_leaf(_list_head, NULL); _iter != NULL; _iter = fr_pair_list_iter_leaf(_list_head, _iter))
273 
274 /** Append a pair to a list, assigning its value.
275  *
276  * Version for simple C data types
277  *
278  * @param[in] _ctx to allocate the pair in
279  * @param[out] _vp the allocated pair
280  * @param[in] _list to append the pair to
281  * @param[in] _attr to use when creating pair
282  * @param[in] _val to assign to the pair
283  * @param[in] _tainted does the value come from a trusted source
284  */
285 #define fr_pair_list_append_by_da(_ctx, _vp, _list, _attr, _val, _tainted) \
286 do { \
287  _vp = NULL; \
288  if (fr_pair_append_by_da(_ctx, &_vp, _list, _attr) < 0) break; \
289  fr_value_box(&_vp->data, _val, _tainted); \
290  if (!vp_da_data_type_check(_vp)) { \
291  fr_pair_delete(_list, _vp); \
292  _vp = NULL; \
293  } \
294 } while (0)
295 
296 /** Append a pair to a list, assigning its value.
297  *
298  * Version for char* and uint8_t*
299  *
300  * @param[in] _ctx to allocate the pair in
301  * @param[out] _vp the allocated pair
302  * @param[in] _list to append the pair to
303  * @param[in] _attr to use when creating pair
304  * @param[in] _val to assign to the pair
305  * @param[in] _len of value
306  * @param[in] _tainted does the value come from a trusted source
307  */
308 #define fr_pair_list_append_by_da_len(_ctx, _vp, _list, _attr, _val, _len, _tainted) \
309 do { \
310  _vp = NULL; \
311  if (fr_pair_append_by_da(_ctx, &_vp, _list, _attr) < 0) break; \
312  fr_value_box_len(_vp, &_vp->data, _val, _len, _tainted); \
313  if (!vp_da_data_type_check(_vp)) { \
314  fr_pair_delete(_list, _vp); \
315  _vp = NULL; \
316  } \
317 } while (0)
318 
319 #define fr_pair_list_append_by_da_parent(_ctx, _vp, _list, _attr, _val, _tainted) \
320 do { \
321  _vp = NULL; \
322  if (fr_pair_append_by_da_parent(_ctx, &_vp, _list, _attr) < 0) break; \
323  fr_value_box(&_vp->data, _val, _tainted); \
324  if (!vp_da_data_type_check(_vp)) { \
325  fr_pair_delete(_list, _vp); \
326  _vp = NULL; \
327  } \
328 } while (0)
329 
330 #define fr_pair_list_append_by_da_parent_len(_ctx, _vp, _list, _attr, _val, _len, _tainted) \
331 do { \
332  _vp = NULL; \
333  if (fr_pair_append_by_da_parent(_ctx, &vp, _list, _attr) < 0) break; \
334  fr_value_box_len(_vp, &_vp->data, _val, _len, _tainted); \
335  if (!vp_da_data_type_check(_vp)) { \
336  fr_pair_delete(_list, _vp); \
337  _vp = NULL; \
338  } \
339 } while (0)
340 
341 /** Prepend a pair to a list, assigning its value
342  *
343  * Version for simple C data types
344  *
345  * @param[in] _ctx to allocate the pair in
346  * @param[out] _vp the allocated pair
347  * @param[in] _list to prepend the pair to
348  * @param[in] _attr to use when creating pair
349  * @param[in] _val to assign to the pair
350  * @param[in] _tainted does the value come from a trusted source
351  */
352 #define fr_pair_list_prepend_by_da(_ctx, _vp, _list, _attr, _val, _tainted) \
353 do { \
354  _vp = NULL; \
355  if (fr_pair_prepend_by_da(_ctx, &_vp, _list, _attr) < 0) break; \
356  fr_value_box(&_vp->data, _val, _tainted); \
357  if (!vp_da_data_type_check(_vp)) { \
358  fr_pair_delete(_list, _vp); \
359  _vp = NULL; \
360  } \
361 } while (0)
362 
363 /** Prepend a pair to a list, assigning its value.
364  *
365  * Version for char* and uint8_t*
366  *
367  * @param[in] _ctx to allocate the pair in
368  * @param[out] _vp the allocated pair
369  * @param[in] _list to prepend the pair to
370  * @param[in] _attr to use when creating pair
371  * @param[in] _val to assign to the pair
372  * @param[in] _len of value
373  * @param[in] _tainted does the value come from a trusted source
374  */
375 #define fr_pair_list_prepend_by_da_len(_ctx, _vp, _list, _attr, _val, _len, _tainted) \
376 do { \
377  _vp = NULL; \
378  if (fr_pair_prepend_by_da(_ctx, &_vp, _list, _attr) < 0) break; \
379  fr_value_box_len(_vp, &_vp->data, _val, _len, _tainted); \
380  if (!vp_da_data_type_check(_vp)) { \
381  fr_pair_delete(_list, _vp); \
382  _vp = NULL; \
383  } \
384 } while (0)
385 
386 /** Replace a pair in a list, assigning its value
387  *
388  * Version for simple C data types.
389  * If the pair does not already exist, a new one is allocated.
390  *
391  * @param[in] _ctx to allocate the pair in
392  * @param[out] _vp the allocated pair
393  * @param[in] _list to append the pair to
394  * @param[in] _attr to use when creating pair
395  * @param[in] _val to assign to the pair
396  * @param[in] _tainted does the value come from a trusted source
397  */
398 #define fr_pair_list_replace_by_da(_ctx, _vp, _list, _attr, _val, _tainted) \
399 do { \
400  fr_pair_update_by_da(_ctx, _vp, _list, _attr, 0); \
401  if (!vp) break; \
402  fr_value_box(&_vp->data, _val, _tainted); \
403  if (!vp_da_data_type_check(_vp)) { \
404  fr_pair_delete(_list, _vp); \
405  _vp = NULL; \
406  } \
407 } while (0)
408 
409 /** Replace a pair in a list, assigning its value
410  *
411  * Version for char* and uint8_t*
412  * If the pair does not already exist, a new one is allocated.
413  *
414  * @param[in] _ctx to allocate the pair in
415  * @param[out] _vp the allocated pair
416  * @param[in] _list to append the pair to
417  * @param[in] _attr to use when creating pair
418  * @param[in] _val to assign to the pair
419  * @param[in] _len of value
420  * @param[in] _tainted does the value come from a trusted source
421  */
422 #define fr_pair_list_replace_by_da_len(_ctx, _vp, _list, _attr, _val, _len, _tainted) \
423 do { \
424  fr_pair_t *oldvp = fr_pair_find_by_da(_list, NULL, _attr); \
425  fr_pair_list_append_by_da_len(_ctx, _vp_, _list, _attr, _val, _len, _tainted) \
426  if (!vp_da_data_type_check(_vp)) { \
427  fr_pair_delete(_list, _vp); \
428  _vp = NULL; \
429  } \
430  if (!_vp) break; \
431  if (oldvp) fr_pair_delete(_list, oldvp); \
432 } while (0)
433 
434 /* Initialisation */
435 /** @hidecallergraph */
437 
438 void fr_pair_init_null(fr_pair_t *vp) CC_HINT(nonnull);
439 
440 /* Allocation and management */
441 fr_pair_t *fr_pair_alloc_null(TALLOC_CTX *ctx) CC_HINT(warn_unused_result);
442 
443 fr_pair_list_t *fr_pair_list_alloc(TALLOC_CTX *ctx) CC_HINT(warn_unused_result);
444 
445 fr_pair_t *fr_pair_root_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da) CC_HINT(warn_unused_result) CC_HINT(nonnull(2));
446 
447 /** @hidecallergraph */
448 fr_pair_t *fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da) CC_HINT(warn_unused_result) CC_HINT(nonnull(2));
449 
451  CC_HINT(nonnull(2, 3));
452 
453 fr_pair_t *fr_pair_afrom_child_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int attr) CC_HINT(warn_unused_result);
454 
455 fr_pair_t *fr_pair_afrom_da_nested(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_attr_t const *da) CC_HINT(warn_unused_result) CC_HINT(nonnull(2,3));
456 
457 fr_pair_t *fr_pair_afrom_da_depth_nested(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_attr_t const *da, int start) CC_HINT(warn_unused_result) CC_HINT(nonnull(2,3));
458 
459 fr_pair_t *fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp) CC_HINT(nonnull(2)) CC_HINT(warn_unused_result);
460 
461 int fr_pair_steal(TALLOC_CTX *ctx, fr_pair_t *vp) CC_HINT(nonnull);
462 
463 int fr_pair_steal_append(TALLOC_CTX *nctx, fr_pair_list_t *list, fr_pair_t *vp) CC_HINT(nonnull);
464 
465 int fr_pair_steal_prepend(TALLOC_CTX *nctx, fr_pair_list_t *list, fr_pair_t *vp) CC_HINT(nonnull);
466 
467 /* Searching and list modification */
468 int fr_pair_raw_afrom_pair(fr_pair_t *vp, uint8_t const *data, size_t data_len) CC_HINT(nonnull);
469 
470 bool fr_pair_matches_da(void const *item, void const *uctx) CC_HINT(nonnull);
471 
472 /** @hidecallergraph */
473 unsigned int fr_pair_count_by_da(fr_pair_list_t const *list, fr_dict_attr_t const *da)
474  CC_HINT(nonnull);
475 
476 /** @hidecallergraph */
478  fr_pair_t const *prev, fr_dict_attr_t const *da) CC_HINT(nonnull(1,3));
479 
481  fr_dict_attr_t const *da, unsigned int idx) CC_HINT(nonnull);
482 
484  fr_dict_attr_t const *da) CC_HINT(nonnull(1,3));
485 
487  fr_pair_t const *prev, fr_dict_attr_t const *da) CC_HINT(nonnull(1,3));
488 
490  fr_dict_attr_t const *parent, unsigned int attr) CC_HINT(nonnull(1,3));
491 
493  fr_dict_attr_t const *parent, unsigned int attr,
494  unsigned int idx) CC_HINT(nonnull);
495 
496 /** @hidecallergraph */
497 int fr_pair_append(fr_pair_list_t *list, fr_pair_t *vp) CC_HINT(nonnull);
498 
499 int fr_pair_prepend(fr_pair_list_t *list, fr_pair_t *vp) CC_HINT(nonnull);
500 
501 int fr_pair_insert_after(fr_pair_list_t *list, fr_pair_t *pos, fr_pair_t *to_add) CC_HINT(nonnull(1,3));
502 
503 int fr_pair_insert_before(fr_pair_list_t *list, fr_pair_t *pos, fr_pair_t *to_add) CC_HINT(nonnull(1,3));
504 
505 void fr_pair_replace(fr_pair_list_t *list, fr_pair_t *to_replace, fr_pair_t *vp) CC_HINT(nonnull);
506 
508  fr_dict_attr_t const *parent, unsigned int attr) CC_HINT(nonnull);
509 
510 int fr_pair_append_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list,
511  fr_dict_attr_t const *da) CC_HINT(nonnull(3,4));
512 
513 int fr_pair_prepend_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list,
514  fr_dict_attr_t const *da) CC_HINT(nonnull(3,4));
515 
516 int fr_pair_append_by_da_parent(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list,
517  fr_dict_attr_t const *da) CC_HINT(nonnull(3,4));
518 
520  fr_dict_attr_t const *da) CC_HINT(nonnull(1,3));
521 
522 static inline CC_HINT(nonnull(3,4)) int fr_pair_find_or_append_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list,
523  fr_dict_attr_t const *da)
524 {
525  fr_pair_t *vp;
526 
527  vp = fr_pair_find_by_da(list, NULL, da);
528  if (vp) {
529  *out = vp;
530  return 0;
531  }
532 
533  return fr_pair_append_by_da(ctx, out, list, da);
534 }
535 
536 
538 
540 
542 
543 /* functions for FR_TYPE_STRUCTURAL */
545 
547 
549 
551 
553 
554 /** Initialises a special dcursor with callbacks that will maintain the attr sublists correctly
555  *
556  * Filters can be applied later with fr_dcursor_filter_set.
557  *
558  * @note This is the only way to use a dcursor in non-const mode with fr_pair_list_t.
559  *
560  * @param[out] _cursor to initialise.
561  * @param[in] _list to iterate over.
562  * @param[in] _iter Iterator to use when filtering pairs.
563  * @param[in] _uctx To pass to iterator.
564  * @return
565  * - NULL if src does not point to any items.
566  * - The first pair in the list.
567  */
568 #define fr_pair_dcursor_iter_init(_cursor, _list, _iter, _uctx) \
569  _fr_pair_dcursor_iter_init(_cursor, \
570  _list, \
571  _iter, \
572  _uctx, \
573  IS_CONST(fr_pair_list_t *, _list))
575  fr_dcursor_iter_t iter, void const *uctx,
576  bool is_const) CC_HINT(nonnull);
577 
578 /** Initialises a special dcursor with callbacks that will maintain the attr sublists correctly
579  *
580  * Filters can be applied later with fr_dcursor_filter_set.
581  *
582  * @note This is the only way to use a dcursor in non-const mode with fr_pair_list_t.
583  *
584  * @param[out] _cursor to initialise.
585  * @param[in] _list to iterate over.
586  * @return
587  * - NULL if src does not point to any items.
588  * - The first pair in the list.
589  */
590 #define fr_pair_dcursor_init(_cursor, _list) \
591  _fr_pair_dcursor_init(_cursor, \
592  _list, \
593  IS_CONST(fr_pair_list_t *, _list))
595  bool is_const) CC_HINT(nonnull);
596 
597 /** Initializes a child dcursor from a parent cursor, with an iteration function.
598  *
599  * Filters can be applied later with fr_dcursor_filter_set.
600  *
601  * @note This is the only way to use a dcursor in non-const mode with fr_pair_list_t.
602  *
603  * @param[out] cursor to initialise.
604  * @param[in] list to iterate over.
605  * @param[in] parent parent cursor to take the iterator from
606  * @return
607  * - NULL if src does not point to any items.
608  * - The first pair in the list.
609  */
611 {
612  fr_pair_t *vp = fr_pair_dcursor_init(cursor, list);
613 
614  fr_dcursor_copy_iter(cursor, parent);
615  return vp;
616 }
617 
618 /** Initialise a cursor that will return only attributes matching the specified #fr_dict_attr_t
619  *
620  * @param[in] _cursor to initialise.
621  * @param[in] _list to iterate over.
622  * @param[in] _da to search for.
623  * @return
624  * - The first matching pair.
625  * - NULL if no pairs match.
626  */
627 #define fr_pair_dcursor_by_da_init(_cursor, _list, _da) \
628  _fr_pair_dcursor_by_da_init(_cursor, \
629  _list, \
630  _da, \
631  IS_CONST(fr_pair_list_t *, _list))
633  fr_pair_list_t const *list, fr_dict_attr_t const *da,
634  bool is_const) CC_HINT(nonnull);
635 
636 /** Initialise a cursor that will return only attributes descended from the specified #fr_dict_attr_t
637  *
638  * @param[in] _cursor to initialise.
639  * @param[in] _list to iterate over.
640  * @param[in] _da who's decentness to search for.
641  * @return
642  * - The first matching pair.
643  * - NULL if no pairs match.
644  */
645 #define fr_pair_dcursor_by_ancestor_init(_cursor, _list, _da) \
646  _fr_pair_dcursor_by_ancestor_init(_cursor, \
647  _list, \
648  _da, \
649  IS_CONST(fr_pair_list_t *, _list))
651  fr_pair_list_t const *list, fr_dict_attr_t const *da,
652  bool is_const) CC_HINT(nonnull);
653 
655 
657 
658 /** Compare two attributes using and operator.
659  *
660  * @return
661  * - 1 if equal.
662  * - 0 if not equal.
663  * - -1 on failure.
664  */
665 #define fr_pair_cmp_op(_op, _a, _b) fr_value_box_cmp_op(_op, &_a->data, &_b->data)
666 
667 int8_t fr_pair_cmp_by_da(void const *a, void const *b);
668 
669 int8_t fr_pair_cmp_by_parent_num(void const *a, void const *b);
670 
671 int fr_pair_cmp(fr_pair_t const *a, fr_pair_t const *b);
672 
673 int fr_pair_list_cmp(fr_pair_list_t const *a, fr_pair_list_t const *b) CC_HINT(nonnull);
674 
675 /* Filtering */
676 void fr_pair_validate_debug(fr_pair_t const *failed[2]) CC_HINT(nonnull);
677 
678 bool fr_pair_validate(fr_pair_t const *failed[2], fr_pair_list_t *filter,
679  fr_pair_list_t *list) CC_HINT(nonnull(2,3));
680 
681 bool fr_pair_validate_relaxed(fr_pair_t const *failed[2], fr_pair_list_t *filter,
682  fr_pair_list_t *list) CC_HINT(nonnull(2,3));
683 
684 bool fr_pair_immutable(fr_pair_t const *vp) CC_HINT(nonnull);
685 
686 static inline CC_HINT(nonnull, always_inline)
688 {
690 }
691 
692 
693 /* Lists */
694 int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from);
695 
696 void fr_pair_list_steal(TALLOC_CTX *ctx, fr_pair_list_t *list);
697 
699 
700 int fr_pair_list_copy_by_da(TALLOC_CTX *ctx, fr_pair_list_t *to,
701  fr_pair_list_t const *from, fr_dict_attr_t const *da, unsigned int count);
702 
703 int fr_pair_list_copy_by_ancestor(TALLOC_CTX *ctx, fr_pair_list_t *to,
704  fr_pair_list_t const *from,
705  fr_dict_attr_t const *parent_da) CC_HINT(nonnull);
706 
707 int fr_pair_sublist_copy(TALLOC_CTX *ctx, fr_pair_list_t *to,
708  fr_pair_list_t const *from,
709  fr_pair_t const *start, unsigned int count) CC_HINT(nonnull(2,3));
710 
711 #ifndef _PAIR_INLINE
712 /** @hidecallergraph */
713 void fr_pair_list_free(fr_pair_list_t *list) CC_HINT(nonnull);
714 
716 
717 
718 /** @hidecallergraph */
719 bool fr_pair_list_empty(fr_pair_list_t const *list) CC_HINT(nonnull);
720 
721 size_t fr_pair_list_num_elements(fr_pair_list_t const *list) CC_HINT(nonnull);
722 
724 
726 
727 void fr_pair_list_sort(fr_pair_list_t *list, fr_cmp_t cmp) CC_HINT(nonnull);
728 
729 void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src) CC_HINT(nonnull);
730 
732 
733 /** @hidecallergraph */
734 fr_pair_t *fr_pair_list_head(fr_pair_list_t const *list) CC_HINT(nonnull);
735 
736 /** @hidecallergraph */
737 fr_pair_t *fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item) CC_HINT(nonnull(1));
738 
739 fr_pair_t *fr_pair_list_prev(fr_pair_list_t const *list, fr_pair_t const *item) CC_HINT(nonnull(1));
740 
741 fr_pair_t *fr_pair_list_tail(fr_pair_list_t const *list) CC_HINT(nonnull);
742 #endif
743 
744 /** @name Pair to pair copying
745  *
746  * @{
747  */
748 void fr_pair_value_clear(fr_pair_t *vp) CC_HINT(nonnull);
749 
750 int fr_pair_value_copy(fr_pair_t *dst, fr_pair_t *src) CC_HINT(nonnull);
751 /** @} */
752 
753 /** @name Assign and manipulate binary-unsafe C strings
754  *
755  * @{
756  */
758  char const *value, size_t len, fr_sbuff_unescape_rules_t const *erules,
759  bool tainted) CC_HINT(nonnull(1,2));
760 
761 int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted) CC_HINT(nonnull);
762 
763 int fr_pair_value_strdup_shallow(fr_pair_t *vp, char const *src, bool tainted) CC_HINT(nonnull);
764 
766 
768  char const *fmt, ...) CC_HINT(nonnull) CC_HINT(format (printf, 2, 3));
769 /** @} */
770 
771 /** @name Assign and manipulate binary-safe strings
772  *
773  * @{
774  */
775 int fr_pair_value_bstr_alloc(fr_pair_t *vp, char **out, size_t size, bool tainted) CC_HINT(nonnull(1));
776 
777 int fr_pair_value_bstr_realloc(fr_pair_t *vp, char **out, size_t size) CC_HINT(nonnull(1));
778 
779 int fr_pair_value_bstrndup(fr_pair_t *vp, char const *src, size_t len, bool tainted) CC_HINT(nonnull(1));
780 
781 int fr_pair_value_bstrdup_buffer(fr_pair_t *vp, char const *src, bool tainted) CC_HINT(nonnull);
782 
783 int fr_pair_value_bstrndup_shallow(fr_pair_t *vp, char const *src, size_t len, bool tainted) CC_HINT(nonnull(1));
784 
785 int fr_pair_value_bstrdup_buffer_shallow(fr_pair_t *vp, char const *src, bool tainted) CC_HINT(nonnull);
786 
787 int fr_pair_value_bstrn_append(fr_pair_t *vp, char const *src, size_t len, bool tainted) CC_HINT(nonnull(1));
788 
789 int fr_pair_value_bstr_append_buffer(fr_pair_t *vp, char const *src, bool tainted) CC_HINT(nonnull);
790  /** @} */
791 
792 /** @name Assign and manipulate octets strings
793  *
794  * @{
795  */
796 int fr_pair_value_mem_alloc(fr_pair_t *vp, uint8_t **out, size_t size, bool tainted) CC_HINT(nonnull(1));
797 
798 int fr_pair_value_mem_realloc(fr_pair_t *vp, uint8_t **out, size_t size) CC_HINT(nonnull(1));
799 
800 int fr_pair_value_memdup(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted) CC_HINT(nonnull(1));
801 
802 int fr_pair_value_memdup_buffer(fr_pair_t *vp, uint8_t const *src, bool tainted) CC_HINT(nonnull);
803 
804 int fr_pair_value_memdup_shallow(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted) CC_HINT(nonnull(1));
805 
806 int fr_pair_value_memdup_buffer_shallow(fr_pair_t *vp, uint8_t const *src, bool tainted) CC_HINT(nonnull);
807 
808 int fr_pair_value_mem_append(fr_pair_t *vp, uint8_t *src, size_t len, bool tainted) CC_HINT(nonnull(1));
809 
810 int fr_pair_value_mem_append_buffer(fr_pair_t *vp, uint8_t *src, bool tainted) CC_HINT(nonnull);
811  /** @} */
812 
813 /** @name Enum functions
814  *
815  * @{
816  */
817 char const *fr_pair_value_enum(fr_pair_t const *vp, char buff[static 20]) CC_HINT(nonnull);
818 
820 /** @} */
821 
822 /** @name Printing functions
823  *
824  * @{
825  */
827  fr_pair_t const *vp, fr_token_t quote) CC_HINT(nonnull);
828 
829 static inline fr_slen_t CC_HINT(nonnull(2,3))
830  fr_pair_aprint_value_quoted(TALLOC_CTX *ctx, char **out,
831  fr_pair_t const *vp, fr_token_t quote)
833 
835  fr_pair_t const *vp) CC_HINT(nonnull(1,3));
836 
838  fr_pair_t const *vp) CC_HINT(nonnull(1,3));
839 
841 
842 static inline fr_slen_t CC_HINT(nonnull(2,4))
843  fr_pair_aprint(TALLOC_CTX *ctx, char **out, fr_dict_attr_t const *parent, fr_pair_t const *vp)
845 
846 static inline fr_slen_t CC_HINT(nonnull(2,4))
847  fr_pair_aprint_secure(TALLOC_CTX *ctx, char **out, fr_dict_attr_t const *parent, fr_pair_t const *vp)
849 
850 #define fr_pair_list_log(_log, _lvl, _list) _fr_pair_list_log(_log, _lvl, NULL, _list, __FILE__, __LINE__)
851 void _fr_pair_list_log(fr_log_t const *log, int lvl, fr_pair_t *parent,
852  fr_pair_list_t const *list, char const *file, int line) CC_HINT(nonnull(1,4));
853 
854 void fr_pair_list_debug(fr_pair_list_t const *list) CC_HINT(nonnull);
855 void fr_pair_debug(fr_pair_t const *pair) CC_HINT(nonnull);
856 
857 /** @} */
858 
859 void fr_pair_list_tainted(fr_pair_list_t *vps) CC_HINT(nonnull);
860 
861 void fr_pair_list_afrom_box(TALLOC_CTX *ctx, fr_pair_list_t *out,
862  fr_dict_t const *dict, fr_value_box_t *box) CC_HINT(nonnull);
863 
864 /* Tokenization */
865 typedef struct {
866  TALLOC_CTX *ctx; //!< to allocate VPs in
867  fr_dict_attr_t const *parent; //!< current attribute to allocate VPs in
868  fr_pair_list_t *list; //!< of VPs to add
869 } fr_pair_ctx_t;
870 
871 ssize_t fr_pair_ctx_afrom_str(fr_pair_ctx_t *pair_ctx, char const *in, size_t inlen) CC_HINT(nonnull);
872 void fr_pair_ctx_reset(fr_pair_ctx_t *pair_ctx, fr_dict_t const *dict) CC_HINT(nonnull);
873 
874 void fr_fprintf_pair(FILE *fp, char const *msg, fr_pair_t const *vp);
875 void fr_fprintf_pair_list(FILE *fp, fr_pair_list_t const *list);
876 
877 #undef _CONST
878 #ifdef __cplusplus
879 }
880 #endif
int const char * file
Definition: acutest.h:702
log_entry msg
Definition: acutest.h:794
static int const char * fmt
Definition: acutest.h:573
int const char int line
Definition: acutest.h:702
static fr_dict_t * dict
Definition: fuzzer.c:46
#define DIAG_ON(_x)
Definition: build.h:419
#define RCSIDH(h, id)
Definition: build.h:445
#define DIAG_OFF(_x)
Definition: build.h:418
void *(* fr_dcursor_iter_t)(fr_dlist_head_t *list, void *to_eval, void *uctx)
Callback for implementing custom iterators.
Definition: dcursor.h:51
static void fr_dcursor_copy_iter(fr_dcursor_t *out, fr_dcursor_t const *in)
Copy a read-only iterator from a parent to a child cursor.
Definition: dcursor.h:206
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:137
static fr_slen_t in
Definition: dict.h:645
Test enumeration values.
Definition: dict_test.h:92
Head of a doubly linked list.
Definition: dlist.h:51
static void * item(fr_lst_t const *lst, fr_lst_index_t idx)
Definition: lst.c:122
fr_type_t
Definition: merged_model.c:80
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
ssize_t fr_slen_t
Definition: merged_model.c:35
int8_t(* fr_cmp_t)(void const *a, void const *b)
Definition: misc.h:38
#define SBUFF_OUT_TALLOC_FUNC_NO_LEN_DEF(_func,...)
Set of parsing rules for *unescape_until functions.
Definition: merged_model.c:163
static char buff[sizeof("18446744073709551615")+3]
Definition: size_tests.c:41
return count
Definition: module.c:175
fr_aka_sim_id_type_t type
Definition: log.h:96
bool _CONST is_child
is a child of a VP
Definition: pair.h:55
FR_TLIST_HEAD(fr_pair_order_list) order
Maintains the relative order of pairs in a list.
Stores an attribute, a value and various bits of other data.
Definition: pair.h:68
FR_TLIST_ENTRY(fr_pair_order_list) _CONST order_entry
Entry to maintain relative order within a list.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
Definition: pair.h:69
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition: table.h:253
#define FR_TLIST_TYPES(_name)
Define type specific wrapper structs for tlists.
Definition: tlist.h:776
enum fr_token fr_token_t
static fr_slen_t head
Definition: xlat.h:408
bool fr_pair_matches_da(void const *item, void const *uctx)
Evaluation function for matching if vp matches a given da.
Definition: pair.c:3483
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
Definition: pair_inline.c:43
int fr_pair_list_copy_by_da(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from, fr_dict_attr_t const *da, unsigned int count)
Duplicate pairs in a list matching the specified da.
Definition: pair.c:2403
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp))
Copy a single valuepair.
Definition: pair.c:484
int fr_pair_value_bstr_alloc(fr_pair_t *vp, char **out, size_t size, bool tainted))
Pre-allocate a memory buffer for a "string" type value pair.
Definition: pair.c:2727
int fr_pair_list_cmp(fr_pair_list_t const *a, fr_pair_list_t const *b)
Determine equality of two lists.
Definition: pair.c:2044
int fr_pair_value_memdup_buffer(fr_pair_t *vp, uint8_t const *src, bool tainted)
Copy data from a talloced buffer into an "octets" data type.
Definition: pair.c:3008
fr_dlist_head_t * fr_pair_list_to_dlist(fr_pair_list_t const *list)
Get the dlist head from a pair list.
Definition: pair_inline.c:162
TALLOC_CTX * ctx
to allocate VPs in
Definition: pair.h:866
int fr_pair_value_mem_alloc(fr_pair_t *vp, uint8_t **out, size_t size, bool tainted))
Pre-allocate a memory buffer for a "octets" type value pair.
Definition: pair.c:2927
struct pair_list_s fr_pair_list_t
unsigned int fr_pair_count_by_da(fr_pair_list_t const *list, fr_dict_attr_t const *da)
Return the number of instances of a given da in the specified list.
Definition: pair.c:665
fr_pair_t * fr_pair_find_by_child_num_idx(fr_pair_list_t const *list, fr_dict_attr_t const *parent, unsigned int attr, unsigned int idx)
Find the pair with the matching child attribute at a given index.
Definition: pair.c:888
int fr_pair_value_from_str(fr_pair_t *vp, char const *value, size_t len, fr_sbuff_unescape_rules_t const *erules, bool tainted))
Convert string value to native attribute value.
Definition: pair.c:2586
int fr_pair_sublist_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from, fr_pair_t const *start, unsigned int count))
Duplicate a list of pairs starting at a particular item.
Definition: pair.c:2505
int fr_pair_value_enum_box(fr_value_box_t const **out, fr_pair_t *vp)
Get value box of a VP, optionally prefer enum value.
Definition: pair.c:3161
int fr_pair_value_aprintf(fr_pair_t *vp, char const *fmt,...)
Print data into an "string" data type.
Definition: pair.c:2695
int fr_pair_delete_by_da_nested(fr_pair_list_t *list, fr_dict_attr_t const *da)
Delete matching pairs from the specified list, and prune any empty branches.
Definition: pair.c:1708
int fr_pair_insert_after(fr_pair_list_t *list, fr_pair_t *pos, fr_pair_t *to_add))
Add a VP after another VP.
Definition: pair.c:1368
void fr_fprintf_pair_list(FILE *fp, fr_pair_list_t const *list)
Definition: pair.c:3617
int fr_pair_value_memdup(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted))
Copy data into an "octets" data type.
Definition: pair.c:2978
bool fr_pair_validate_relaxed(fr_pair_t const *failed[2], fr_pair_list_t *filter, fr_pair_list_t *list))
Uses fr_pair_cmp to verify all fr_pair_ts in list match the filter defined by check.
Definition: pair.c:2202
fr_pair_t * fr_pair_list_tail(fr_pair_list_t const *list)
Get the tail of a valuepair list.
Definition: pair_inline.c:56
fr_pair_t * fr_pair_alloc_null(TALLOC_CTX *ctx)
Dynamically allocate a new attribute with no fr_dict_attr_t assigned.
Definition: pair.c:167
fr_pair_t * fr_pair_remove(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list without freeing.
Definition: pair_inline.c:94
static bool vp_da_data_type_check(fr_pair_t *vp)
Check a pair's data type matches the DA data type.
Definition: pair.h:241
fr_pair_t * fr_pair_parent(fr_pair_t const *vp)
Return a pointer to the parent pair.
Definition: pair.c:937
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
Definition: pair.c:278
fr_pair_t * fr_pair_find_by_child_num(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *parent, unsigned int attr))
Find the pair with the matching child attribute.
Definition: pair.c:862
int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from)
Duplicate a list of pairs.
Definition: pair.c:2316
static fr_pair_t * fr_pair_dcursor_child_iter_init(fr_dcursor_t *cursor, fr_pair_list_t const *list, fr_dcursor_t const *parent)
Initializes a child dcursor from a parent cursor, with an iteration function.
Definition: pair.h:610
int fr_pair_value_mem_realloc(fr_pair_t *vp, uint8_t **out, size_t size))
Change the length of a buffer for a "octets" type value pair.
Definition: pair.c:2952
int fr_pair_insert_before(fr_pair_list_t *list, fr_pair_t *pos, fr_pair_t *to_add))
Add a VP before another VP.
Definition: pair.c:1401
int fr_pair_value_mem_append_buffer(fr_pair_t *vp, uint8_t *src, bool tainted)
Append a talloced buffer to an existing "octets" type value pair.
Definition: pair.c:3098
static fr_slen_t fr_pair_aprint(TALLOC_CTX *ctx, char **out, fr_dict_attr_t const *parent, fr_pair_t const *vp) 1(fr_pair_print
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
Definition: pair_inline.c:125
fr_pair_t * fr_pair_find_last_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da))
Find the last pair with a matching da.
Definition: pair.c:712
int fr_pair_append_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, fr_dict_attr_t const *da))
Alloc a new fr_pair_t (and append)
Definition: pair.c:1461
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
Definition: pair_inline.c:70
void fr_pair_validate_debug(fr_pair_t const *failed[2])
Write an error to the library errorbuff detailing the mismatch.
Definition: pair.c:2090
int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
Definition: pair.c:2631
int fr_pair_steal_append(TALLOC_CTX *nctx, fr_pair_list_t *list, fr_pair_t *vp)
Change a vp's talloc ctx and insert it into a new list.
Definition: pair.c:541
int fr_pair_value_bstrdup_buffer_shallow(fr_pair_t *vp, char const *src, bool tainted)
Assign a string to a "string" type value pair.
Definition: pair.c:2852
void fr_pair_init_null(fr_pair_t *vp)
Initialise fields in an fr_pair_t without assigning a da.
Definition: pair.c:147
fr_pair_t * _fr_pair_dcursor_by_da_init(fr_dcursor_t *cursor, fr_pair_list_t const *list, fr_dict_attr_t const *da, bool is_const)
Initialise a cursor that will return only attributes matching the specified fr_dict_attr_t.
Definition: pair.c:1138
int8_t fr_pair_cmp_by_parent_num(void const *a, void const *b)
Order attributes by their parent(s), attribute number, and tag.
Definition: pair.c:1918
int fr_pair_delete_by_da(fr_pair_list_t *head, fr_dict_attr_t const *da)
Delete matching pairs from the specified list.
Definition: pair.c:1684
void fr_pair_list_sort(fr_pair_list_t *list, fr_cmp_t cmp)
Sort a doubly linked list of fr_pair_ts using merge sort.
Definition: pair_inline.c:140
int fr_pair_cmp(fr_pair_t const *a, fr_pair_t const *b)
Compare two pairs, using the operator from "a".
Definition: pair.c:1966
void fr_pair_list_debug(fr_pair_list_t const *list)
Dumps a list to the default logging destination - Useful for calling from debuggers.
Definition: pair_print.c:296
fr_pair_t * fr_pair_find_by_da_nested(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da))
Find a pair with a matching fr_dict_attr_t, by walking the nested fr_dict_attr_t tree.
Definition: pair.c:765
void fr_pair_replace(fr_pair_list_t *list, fr_pair_t *to_replace, fr_pair_t *vp)
Replace a given VP.
Definition: pair.c:1434
int fr_pair_prepend(fr_pair_list_t *list, fr_pair_t *vp)
Add a VP to the start of the list.
Definition: pair.c:1309
int fr_pair_value_memdup_shallow(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted))
Assign a buffer to a "octets" type value pair.
Definition: pair.c:3033
int fr_pair_value_bstrdup_buffer(fr_pair_t *vp, char const *src, bool tainted)
Copy a nul terminated talloced buffer a "string" type value pair.
Definition: pair.c:2807
int fr_pair_list_copy_by_ancestor(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from, fr_dict_attr_t const *parent_da)
Duplicate pairs in a list where the da is a descendant of parent_da.
Definition: pair.c:2452
static bool fr_pair_nonnull_assert(fr_pair_t const *vp)
If WITH_VERIFY_PTR is defined, we perform runtime checks to ensure the fr_pair_t are sane.
Definition: pair.h:174
fr_pair_t * fr_pair_delete(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list and free.
Definition: pair.c:1819
static fr_slen_t quote ssize_t fr_pair_print(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_pair_t const *vp))
Print one attribute and value to a string.
Definition: pair_print.c:89
int fr_pair_value_bstrndup(fr_pair_t *vp, char const *src, size_t len, bool tainted))
Copy data into a "string" type value pair.
Definition: pair.c:2781
static int fr_pair_find_or_append_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, fr_dict_attr_t const *da)
Definition: pair.h:522
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
Definition: pair_inline.c:113
void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src)
Appends a list of fr_pair_t from a temporary list to a destination list.
Definition: pair_inline.c:182
fr_pair_t * fr_pair_afrom_da_nested(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_attr_t const *da)
Create a pair (and all intermediate parents), and append it to the list.
Definition: pair.c:462
void fr_pair_ctx_reset(fr_pair_ctx_t *pair_ctx, fr_dict_t const *dict)
Reset a pair_ctx to the dictionary root.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *vp)
Add a VP to the end of the list.
Definition: pair.c:1340
fr_pair_t * fr_pair_afrom_child_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int attr)
Create a new valuepair.
Definition: pair.c:366
#define _CONST
Definition: pair.h:43
void fr_fprintf_pair(FILE *fp, char const *msg, fr_pair_t const *vp)
Definition: pair.c:3625
int fr_pair_value_bstr_append_buffer(fr_pair_t *vp, char const *src, bool tainted)
Append a talloced buffer to an existing "string" type value pair.
Definition: pair.c:2900
int fr_pair_value_bstrndup_shallow(fr_pair_t *vp, char const *src, size_t len, bool tainted))
Assign a string to a "string" type value pair.
Definition: pair.c:2832
fr_pair_t * _fr_pair_dcursor_by_ancestor_init(fr_dcursor_t *cursor, fr_pair_list_t const *list, fr_dict_attr_t const *da, bool is_const)
Initialise a cursor that will return only attributes descended from the specified fr_dict_attr_t.
Definition: pair.c:1157
void fr_pair_list_prepend(fr_pair_list_t *dst, fr_pair_list_t *src)
Move a list of fr_pair_t from a temporary list to the head of a destination list.
Definition: pair_inline.c:195
bool fr_pair_immutable(fr_pair_t const *vp)
Definition: pair.c:2277
void fr_pair_list_tainted(fr_pair_list_t *vps)
Mark up a list of VPs as tainted.
Definition: pair.c:3454
void fr_pair_value_clear(fr_pair_t *vp)
Free/zero out value (or children) of a given VP.
Definition: pair.c:2530
static void fr_pair_set_immutable(fr_pair_t *vp)
Definition: pair.h:687
fr_pair_list_t * list
of VPs to add
Definition: pair.h:868
void fr_pair_debug(fr_pair_t const *pair)
Dumps a pair to the default logging destination - Useful for calling from debuggers.
Definition: pair_print.c:305
fr_pair_t * fr_pair_find_by_da_idx(fr_pair_list_t const *list, fr_dict_attr_t const *da, unsigned int idx)
Find a pair with a matching da at a given index.
Definition: pair.c:736
fr_pair_list_t * fr_pair_list_from_dlist(fr_dlist_head_t const *list)
Get the pair list head from a dlist.
Definition: pair_inline.c:172
static fr_slen_t vp
Definition: pair.h:832
int fr_pair_delete_by_child_num(fr_pair_list_t *list, fr_dict_attr_t const *parent, unsigned int attr)
Delete matching pairs from the specified list.
Definition: pair.c:1803
int fr_pair_value_copy(fr_pair_t *dst, fr_pair_t *src)
Copy the value from one pair to another.
Definition: pair.c:2560
static bool fr_pair_list_nonnull_assert(fr_pair_list_t const *pair_list)
Definition: pair.h:179
fr_pair_list_t * fr_pair_list_alloc(TALLOC_CTX *ctx)
Allocate a new pair list on the heap.
Definition: pair.c:117
ssize_t fr_pair_print_value_quoted(fr_sbuff_t *out, fr_pair_t const *vp, fr_token_t quote)
Print the value of an attribute to a string.
Definition: pair_print.c:40
fr_pair_t * fr_pair_list_prev(fr_pair_list_t const *list, fr_pair_t const *item))
Get the previous item in a valuepair list before a specific entry.
Definition: pair_inline.c:83
int fr_pair_steal(TALLOC_CTX *ctx, fr_pair_t *vp)
Steal one VP.
Definition: pair.c:516
bool fr_pair_validate(fr_pair_t const *failed[2], fr_pair_list_t *filter, fr_pair_list_t *list))
Uses fr_pair_cmp to verify all fr_pair_ts in list match the filter defined by check.
Definition: pair.c:2125
static fr_slen_t fr_pair_aprint_value_quoted(TALLOC_CTX *ctx, char **out, fr_pair_t const *vp, fr_token_t quote) 1(fr_pair_print_value_quoted
fr_pair_t * _fr_pair_dcursor_iter_init(fr_dcursor_t *cursor, fr_pair_list_t const *list, fr_dcursor_iter_t iter, void const *uctx, bool is_const)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
Definition: pair.c:1098
int fr_pair_append_by_da_parent(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, fr_dict_attr_t const *da))
Alloc a new fr_pair_t, adding the parent attributes if required.
Definition: pair.c:1518
fr_pair_list_t * fr_pair_parent_list(fr_pair_t const *vp)
Return a pointer to the parent pair list.
Definition: pair.c:922
ssize_t fr_pair_ctx_afrom_str(fr_pair_ctx_t *pair_ctx, char const *in, size_t inlen)
Parse a pair context from a string.
int fr_pair_value_strtrim(fr_pair_t *vp)
Trim the length of the string buffer to match the length of the C string.
Definition: pair.c:2674
#define fr_pair_dcursor_init(_cursor, _list)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
Definition: pair.h:590
void _fr_pair_list_log(fr_log_t const *log, int lvl, fr_pair_t *parent, fr_pair_list_t const *list, char const *file, int line))
Print a list of attributes and enumv.
Definition: pair_print.c:283
fr_dict_attr_t const * parent
current attribute to allocate VPs in
Definition: pair.h:867
int fr_pair_update_by_da_parent(fr_pair_t *parent, fr_pair_t **out, fr_dict_attr_t const *da))
Return the first fr_pair_t matching the fr_dict_attr_t or alloc a new fr_pair_t and its subtree (and ...
Definition: pair.c:1591
void fr_pair_list_init(fr_pair_list_t *head)
Initialise a pair list header.
Definition: pair.c:46
int fr_pair_reinit_from_da(fr_pair_list_t *list, fr_pair_t *vp, fr_dict_attr_t const *da))
Re-initialise an attribute with a different da.
Definition: pair.c:309
int fr_pair_value_bstr_realloc(fr_pair_t *vp, char **out, size_t size))
Change the length of a buffer for a "string" type value pair.
Definition: pair.c:2752
int fr_pair_value_mem_append(fr_pair_t *vp, uint8_t *src, size_t len, bool tainted))
Append bytes from a buffer to an existing "octets" type value pair.
Definition: pair.c:3075
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da))
Find the first pair with a matching da.
Definition: pair.c:688
int fr_pair_value_bstrn_append(fr_pair_t *vp, char const *src, size_t len, bool tainted))
Append bytes from a buffer to an existing "string" type value pair.
Definition: pair.c:2877
void fr_pair_list_afrom_box(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_t const *dict, fr_value_box_t *box)
Parse a list of VPs from a value box.
Definition: pair.c:3579
fr_value_box_t * fr_pair_dcursor_nested_init(fr_dcursor_t *cursor, fr_dcursor_t *parent)
Initialises a special dcursor over another cursor which returns fr_pair_t, but we return fr_value_box...
Definition: pair.c:1293
void fr_pair_list_steal(TALLOC_CTX *ctx, fr_pair_list_t *list)
Steal a list of pairs to a new context.
Definition: pair.c:2297
fr_pair_t * fr_pair_list_parent(fr_pair_list_t const *list)
Return a pointer to the parent pair which contains this list.
Definition: pair.c:951
size_t fr_pair_list_num_elements(fr_pair_list_t const *list)
Get the length of a list of fr_pair_t.
Definition: pair_inline.c:151
int fr_pair_steal_prepend(TALLOC_CTX *nctx, fr_pair_list_t *list, fr_pair_t *vp)
Change a vp's talloc ctx and insert it into a new list.
Definition: pair.c:564
int fr_pair_prepend_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, fr_dict_attr_t const *da))
Alloc a new fr_pair_t (and prepend)
Definition: pair.c:1488
fr_pair_t * fr_pair_list_iter_leaf(fr_pair_list_t *list, fr_pair_t *vp)
Iterates over the leaves of a list.
Definition: pair.c:1033
int fr_pair_raw_afrom_pair(fr_pair_t *vp, uint8_t const *data, size_t data_len)
Mark malformed attribute as raw.
Definition: pair.c:588
fr_value_box_t * fr_pair_dcursor_value_init(fr_dcursor_t *cursor)
Initialises a special dcursor over a fr_pair_list_t, but which returns fr_value_box_t.
Definition: pair.c:1243
fr_pair_list_t * fr_pair_children(fr_pair_t *head)
Get the child list of a group.
Definition: pair.c:912
ssize_t fr_pair_print_secure(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_pair_t const *vp))
Print one attribute and value to a string with escape rules.
Definition: pair_print.c:139
int8_t fr_pair_cmp_by_da(void const *a, void const *b)
Order attributes by their da, and tag.
Definition: pair.c:1841
int fr_pair_value_memdup_buffer_shallow(fr_pair_t *vp, uint8_t const *src, bool tainted)
Assign a talloced buffer to a "octets" type value pair.
Definition: pair.c:3053
int fr_pair_value_strdup_shallow(fr_pair_t *vp, char const *src, bool tainted)
Assign a buffer containing a nul terminated string to a vp, but don't copy it.
Definition: pair.c:2655
ssize_t fr_pair_list_print(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_pair_list_t const *list)
Print a pair list.
Definition: pair_print.c:211
fr_pair_t * _fr_pair_dcursor_init(fr_dcursor_t *cursor, fr_pair_list_t const *list, bool is_const)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
Definition: pair.c:1120
static fr_slen_t parent
Definition: pair.h:844
fr_pair_t * fr_pair_root_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
A special allocation function which disables child autofree.
Definition: pair.c:238
fr_pair_t * fr_pair_afrom_da_depth_nested(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_attr_t const *da, int start)
Create a pair (and all intermediate parents), and append it to the list.
Definition: pair.c:403
char const * fr_pair_value_enum(fr_pair_t const *vp, char buff[static 20])
int fr_pair_list_copy_to_box(fr_value_box_t *dst, fr_pair_list_t *from)
Copy the contents of a pair list to a set of value-boxes.
Definition: pair.c:2351
static fr_slen_t static vp fr_slen_t fr_pair_aprint_secure(TALLOC_CTX *ctx, char **out, fr_dict_attr_t const *parent, fr_pair_t const *vp) 1(fr_pair_print_secure
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64
fr_table_num_ordered_t const fr_type_table[]
Map data types to names representing those types.
Definition: types.c:31
static fr_slen_t data
Definition: value.h:1259
static size_t char fr_sbuff_t size_t inlen
Definition: value.h:984
int nonnull(2, 5))
static void fr_value_box_set_immutable(fr_value_box_t *box)
Definition: value.h:1073
int format(printf, 5, 0))
static size_t char ** out
Definition: value.h:984