]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
pair/value: Add utility functions for clearing values
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 24 May 2020 22:11:20 +0000 (17:11 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 24 May 2020 22:11:20 +0000 (17:11 -0500)
src/lib/util/pair.c
src/lib/util/pair.h
src/lib/util/pair_legacy.c
src/lib/util/value.c
src/lib/util/value.h

index 0a4998c2020e5980d1565d0924568c0a535f9ee1..88f2a7a6e5ee318ee5db58f127101150b99f193f 100644 (file)
@@ -1418,6 +1418,54 @@ int fr_pair_list_copy_by_ancestor(TALLOC_CTX *ctx, VALUE_PAIR **to,
        return cnt;
 }
 
+/** Free/zero out value (or children) of a given VP
+ *
+ * @param[in] vp to clear value from.
+ */
+void fr_pair_value_clear(VALUE_PAIR *vp)
+{
+       switch (vp->da->type) {
+       default:
+               fr_value_box_clear_value(&vp->data);
+               return;
+
+       case FR_TYPE_STRUCTURAL:
+               /*
+                *      Depth first freeing of children
+                *
+                *      This ensures orderly freeing, regardless
+                *      of talloc hierarchy.
+                */
+               switch (vp->children.type) {
+               case FR_PAIR_LIST_SINGLE:
+               {
+                       fr_cursor_t     cursor;
+                       VALUE_PAIR      *vpc;
+
+                       for (vpc = fr_cursor_init(&cursor, &vp->children.slist);
+                            vpc;
+                            vpc = fr_cursor_next(&cursor)) {
+                               fr_pair_value_clear(vpc);
+                               talloc_free(vpc);
+                       }
+               }
+                       break;
+
+               case FR_PAIR_LIST_DOUBLE:
+               {
+                       VALUE_PAIR      *vpc = NULL;
+
+                       while ((vpc = fr_dlist_next(&vp->children.dlist, vpc))) {
+                               fr_pair_value_clear(vpc);
+                               talloc_free(vpc);
+                       }
+               }
+                       break;
+               }
+               return;
+       }
+}
+
 /** Copy the value from one pair to another
  *
  * @param[out] out     where to copy the value to.
index 4128df6193c86b8dec301d775b0b4f15c153bb7d..23564a06e94dc52fdcbe6360c054c8db08ca7df7 100644 (file)
@@ -79,7 +79,7 @@ typedef enum {
 typedef struct {
        union {
                VALUE_PAIR              *slist;                 //!< The head of the list.
-               fr_dlist_head_t         *dlist;                 //!< Doubly linked list head.
+               fr_dlist_head_t         dlist;                  //!< Doubly linked list head.
        };
        fr_pair_list_type_t type;                               //!< What type of list this is.
 } fr_pair_list_t;
@@ -329,6 +329,7 @@ int         fr_pair_list_copy_by_ancestor(TALLOC_CTX *ctx, VALUE_PAIR **to,
                                              VALUE_PAIR *from, fr_dict_attr_t const *parent_da);
 
 /* Value manipulation */
+void           fr_pair_value_clear(VALUE_PAIR *vp);
 int            fr_pair_value_copy(VALUE_PAIR *out, VALUE_PAIR *in);
 int            fr_pair_value_from_str(VALUE_PAIR *vp, char const *value, ssize_t len, char quote, bool tainted);
 
index fcf9128829014991138c992281a559b758fce837..7bcd5f2bf496c3f1474f6de4af63ebd2763197c4 100644 (file)
@@ -295,7 +295,7 @@ VALUE_PAIR *fr_pair_make(TALLOC_CTX *ctx, fr_dict_t const *dict, VALUE_PAIR **vp
        switch (vp->op) {
        case T_OP_CMP_TRUE:
        case T_OP_CMP_FALSE:
-               fr_value_box_clear_value(&vp->data);
+               fr_pair_value_clear(vp);
                value = NULL;   /* ignore it! */
                break;
 
index 439138581dfdad70da0867258c0cc2d6f7d93d4a..01650cce612d3a254f8977da31eb3810b38cc483 100644 (file)
@@ -288,62 +288,6 @@ size_t const fr_value_box_offsets[] = {
        [FR_TYPE_MAX]                           = 0     //!< Ensure array covers all types.
 };
 
-/** Clear/free any existing value and metadata
- *
- * @note Do not use on uninitialised memory.
- *
- * @param[in] data to clear.
- */
-inline void fr_value_box_clear(fr_value_box_t *data)
-{
-       switch (data->type) {
-       case FR_TYPE_OCTETS:
-       case FR_TYPE_STRING:
-               talloc_free(data->datum.ptr);
-               break;
-
-       case FR_TYPE_STRUCTURAL:
-               fr_assert_fail(NULL);
-               return;
-
-       case FR_TYPE_INVALID:
-               return;
-
-       default:
-               break;
-       }
-
-       fr_value_box_init(data, FR_TYPE_INVALID, NULL, false);
-}
-
-/** Clear/free any existing value
- *
- * @note Do not use on uninitialised memory.
- *
- * @param[in] data to clear.
- */
-inline void fr_value_box_clear_value(fr_value_box_t *data)
-{
-       switch (data->type) {
-       case FR_TYPE_OCTETS:
-       case FR_TYPE_STRING:
-               talloc_free(data->datum.ptr);
-               break;
-
-       case FR_TYPE_STRUCTURAL:
-               fr_assert_fail(NULL);
-               return;
-
-       case FR_TYPE_INVALID:
-               return;
-
-       default:
-               break;
-       }
-
-       memset(&data->datum, 0, sizeof(data->datum));
-}
-
 /** Copy flags and type data from one value box to another
  *
  * @param[in] dst to copy flags to
@@ -3302,6 +3246,77 @@ int fr_value_unbox_ipaddr(fr_ipaddr_t *dst, fr_value_box_t *src)
        return 0;
 }
 
+/** Clear/free any existing value
+ *
+ * @note Do not use on uninitialised memory.
+ *
+ * @param[in] data to clear.
+ */
+inline void fr_value_box_clear_value(fr_value_box_t *data)
+{
+       switch (data->type) {
+       case FR_TYPE_OCTETS:
+       case FR_TYPE_STRING:
+               talloc_free(data->datum.ptr);
+               break;
+
+       case FR_TYPE_STRUCTURAL:
+               /*
+                *      Depth first freeing of children
+                *
+                *      This ensures orderly freeing, regardless
+                *      of talloc hierarchy.
+                */
+               switch (data->datum.children.type) {
+               case FR_VALUE_BOX_LIST_SINGLE:
+               {
+                       fr_cursor_t     cursor;
+                       fr_value_box_t  *vb;
+
+                       for (vb = fr_cursor_init(&cursor, &data->datum.children.slist);
+                            vb;
+                            vb = fr_cursor_next(&cursor)) {
+                               fr_value_box_clear_value(vb);
+                               talloc_free(vb);
+                       }
+               }
+                       break;
+
+               case FR_VALUE_BOX_LIST_DOUBLE:
+               {
+                       fr_value_box_t  *vb = NULL;
+
+                       while ((vb = fr_dlist_next(&data->datum.children.dlist, vb))) {
+                               fr_value_box_clear_value(vb);
+                               talloc_free(vb);
+                       }
+               }
+                       break;
+               }
+               return;
+
+       case FR_TYPE_INVALID:
+               return;
+
+       default:
+               break;
+       }
+
+       memset(&data->datum, 0, sizeof(data->datum));
+}
+
+/** Clear/free any existing value and metadata
+ *
+ * @note Do not use on uninitialised memory.
+ *
+ * @param[in] data to clear.
+ */
+inline void fr_value_box_clear(fr_value_box_t *data)
+{
+       fr_value_box_clear_value(data);
+       fr_value_box_init(data, FR_TYPE_INVALID, NULL, false);
+}
+
 /** Copy value data verbatim duplicating any buffers
  *
  * @note Will free any exiting buffers associated with the dst #fr_value_box_t.
index cd90ac61244a645a6d755c120fa0a1eba30b4e5c..eb82a0f59bc2acf5d1d777369e3b87d7789dff28 100644 (file)
@@ -80,7 +80,7 @@ typedef enum {
 typedef struct {
        union {
                fr_value_box_t          *slist;                 //!< The head of the list.
-               fr_dlist_head_t         *dlist;                 //!< Doubly linked list head.
+               fr_dlist_head_t         dlist;                  //!< Doubly linked list head.
        };
        fr_value_box_list_type_t type;                          //!< What type of list this is.
 } fr_value_box_list_t;
@@ -533,12 +533,6 @@ _Generic((_var), \
 )(_var, _box)
 
 /** @} */
-/*
- *     Allocation - init/alloc use static functions (above)
- */
-void           fr_value_box_clear(fr_value_box_t *data);
-
-void           fr_value_box_clear_value(fr_value_box_t *data);
 
 /*
  *     Comparison
@@ -591,6 +585,10 @@ int                fr_value_unbox_ipaddr(fr_ipaddr_t *dst, fr_value_box_t *src);
  *
  * @{
  */
+void           fr_value_box_clear_value(fr_value_box_t *data);
+
+void           fr_value_box_clear(fr_value_box_t *data);
+
 int            fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src);
 
 void           fr_value_box_copy_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst,