]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
xlat: Add new name format setting functions
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 19 Feb 2023 22:53:26 +0000 (16:53 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 19 Feb 2023 22:55:47 +0000 (16:55 -0600)
We no longer copy a pointer to the buffer in boxed values as if that box is purified the fmt pointer becomes invalidated, and will cause crashes.

src/lib/unlang/xlat_alloc.c
src/lib/unlang/xlat_expr.c
src/lib/unlang/xlat_priv.h
src/lib/unlang/xlat_tokenize.c

index 24a28ac97e70b924dd1fe9c861075ed557a5e74f..49ac2f9555cbae67d1e63acd38af33e1cca47a53 100644 (file)
@@ -202,6 +202,28 @@ xlat_exp_t *_xlat_exp_alloc(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, xlat_type_t ty
  * @param[in] node     to set fmt for.
  * @param[in] fmt      talloced buffer to set as the fmt string.
  */
+void xlat_exp_set_name(xlat_exp_t *node, char const *fmt, size_t len)
+{
+       if (node->fmt) talloc_const_free(node->fmt);
+       node->fmt = talloc_bstrndup(node, fmt, len);
+}
+
+/** Set the format string for an xlat node, copying from a talloc'd buffer
+ *
+ * @param[in] node     to set fmt for.
+ * @param[in] fmt      talloced buffer to set as the fmt string.
+ */
+void xlat_exp_set_name_buffer(xlat_exp_t *node, char const *fmt)
+{
+       if (node->fmt) talloc_const_free(node->fmt);
+       node->fmt = talloc_typed_strdup_buffer(node, fmt);
+}
+
+/** Set the format string for an xlat node from a pre-existing buffer
+ *
+ * @param[in] node     to set fmt for.
+ * @param[in] fmt      talloced buffer to set as the fmt string.
+ */
 void xlat_exp_set_name_buffer_shallow(xlat_exp_t *node, char const *fmt)
 {
        if (node->fmt) talloc_const_free(node->fmt);
index a1dcbd0dd584629eee3e949d08fe437a4acb7a4b..9664588fba6b470d5c7db7ea5644cab62fe5b37c 100644 (file)
@@ -1066,12 +1066,19 @@ static int xlat_expr_logical_purify(xlat_exp_t *node, void *instance, request_t
         */
        group = inst->argv[0];
        fr_assert(group != NULL);
-       fr_assert(group->fmt != NULL);
        talloc_steal(node, group);
 
        xlat_inst_remove(node);
-       xlat_exp_set_type(node, XLAT_BOX);
-       xlat_exp_set_name_buffer_shallow(node, group->fmt);
+       xlat_exp_set_type(node, XLAT_GROUP);
+
+       /* re-print, with purified nodes removed */
+       {
+               char *name;
+
+               xlat_aprint(node, &name, group, NULL);
+               xlat_exp_set_name_buffer_shallow(node, name);
+       }
+
        node->group = group;
        node->flags = group->flags;
 
@@ -2004,9 +2011,10 @@ static xlat_exp_t *expr_cast_alloc(TALLOC_CTX *ctx, fr_type_t type)
         */
        MEM(node = xlat_exp_alloc(cast, XLAT_BOX, NULL, 0));
        node->flags.constant = true;
-       xlat_exp_set_name_buffer_shallow(node,
-                                        talloc_typed_strdup(node,
-                                                            fr_table_str_by_value(fr_type_table, type, "<INVALID>")));
+       {
+               char const *type_name = fr_table_str_by_value(fr_type_table, type, "<INVALID>");
+               xlat_exp_set_name(node, type_name, strlen(type_name));
+       }
 
        fr_value_box_init(&node->data, FR_TYPE_UINT8, attr_cast_base, false);
        node->data.vb_uint8 = type;
index 2d0751d2ad0fdbd9d59e7102c1749f8674060b0a..8c60c5d973222c5aa6fc245e7ce2a6441347a986 100644 (file)
@@ -179,7 +179,6 @@ struct xlat_exp_s {
 
 struct xlat_exp_head_s {
        fr_dlist_head_t         dlist;
-       char const * _CONST     fmt;            //!< The original format string (a talloced buffer).
        xlat_flags_t            flags;          //!< Flags that control resolution and evaluation.
        bool                    instantiated;   //!< temporary flag until we fix more things
        fr_dict_t const         *dict;          //!< dictionary for this xlat
@@ -310,7 +309,9 @@ xlat_exp_t  *_xlat_exp_alloc_null(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx);
 xlat_exp_t     *_xlat_exp_alloc(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, xlat_type_t type, char const *in, size_t inlen);
 #define                xlat_exp_alloc(_ctx, _type, _in, _inlen) _xlat_exp_alloc(NDEBUG_LOCATION_EXP _ctx, _type, _in, _inlen)
 
+void           xlat_exp_set_name(xlat_exp_t *node, char const *fmt, size_t len) CC_HINT(nonnull);
 void           xlat_exp_set_name_buffer_shallow(xlat_exp_t *node, char const *fmt) CC_HINT(nonnull);
+void           xlat_exp_set_name_buffer(xlat_exp_t *node, char const *fmt) CC_HINT(nonnull);
 
 /*
  *     xlat_func.c
index fb6050729b2f9210d89e662cd6ec1033c3f8d80d..19da8ed7859ce83f0944d445cc8e216d84f0614f 100644 (file)
@@ -934,7 +934,7 @@ static int xlat_tokenize_string(xlat_exp_head_t *head,
                 */
                if (slen > 0) {
                        xlat_exp_set_name_buffer_shallow(node, str);
-                       fr_value_box_strdup_shallow(&node->data, NULL, str, false);
+                       fr_value_box_strdup(node, &node->data, NULL, str, false);
                        node->flags.constant = true;
 
                        XLAT_DEBUG("VALUE-BOX (%s)<-- %pV",
@@ -984,9 +984,9 @@ static int xlat_tokenize_string(xlat_exp_head_t *head,
                                node = xlat_exp_alloc_null(head);
                        }
 
-                       fr_sbuff_out_abstrncpy(node, &str, in, 1);
                        xlat_exp_set_type(node, XLAT_ONE_LETTER);
-                       xlat_exp_set_name_buffer_shallow(node, str);
+                       xlat_exp_set_name(node, fr_sbuff_current(in), 1);
+                       fr_sbuff_next(in);      /* Consumed 1 char */
 
 #ifdef STATIC_ANALYZER
                        if (!node->fmt) goto error;
@@ -1560,7 +1560,7 @@ fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t
                        if (slen < 0) goto error;
 
                        xlat_exp_set_name_buffer_shallow(child, str);
-                       fr_value_box_strdup_shallow(&child->data, NULL, str, false);
+                       fr_value_box_strdup(child, &child->data, NULL, str, false);
                        xlat_exp_insert_tail(node->group, child);
                }
                        break;