/*
* FIXME - We don't yet support async LHS/RHS expansions for map procs
*/
-#ifndef NDEBUG
- if (!fr_dlist_empty(&map_proc_state->src_result)) fr_dlist_verify(&map_proc_state->src_result);
-#endif
+ FR_DLIST_VERIFY(&map_proc_state->src_result);
*p_result = map_proc(request, gext->proc_inst, &map_proc_state->src_result);
-#ifndef NDEBUG
- if (!fr_dlist_empty(&map_proc_state->src_result)) fr_dlist_verify(&map_proc_state->src_result);
-#endif
+ FR_DLIST_VERIFY(&map_proc_state->src_result);
return *p_result == RLM_MODULE_YIELD ? UNLANG_ACTION_YIELD : UNLANG_ACTION_CALCULATE_RESULT;
}
* to debug problems if they free or change elements
* and don't remove them from the list.
*/
- fr_dlist_verify(result);
+ VALUE_BOX_LIST_VERIFY(result);
xa = resume(ctx, out, request, exp->call.inst, thread_inst->data, result, rctx);
- fr_dlist_verify(result);
+ VALUE_BOX_LIST_VERIFY(result);
RDEBUG2("EXPAND %%{%s:...}", exp->call.func->name);
switch (xa) {
ssize_t slen;
if (!fr_dlist_empty(result)) {
- fr_dlist_verify(result);
+ VALUE_BOX_LIST_VERIFY(result);
result_str = fr_value_box_list_aprint(NULL, result, NULL, NULL);
if (!result_str) return XLAT_ACTION_FAIL;
} else {
fr_value_box_bstrdup_buffer_shallow(NULL, value, NULL, str, false);
}
+ VALUE_BOX_VERIFY(value);
fr_dcursor_append(out, value); /* Append the result of the expansion */
talloc_free(result_str);
xlat_debug_log_result(request, value);
*/
if (RDEBUG_ENABLED2) fr_value_box_list_acopy(NULL, &result_copy, result);
- fr_dlist_verify(result);
-
+ VALUE_BOX_LIST_VERIFY(result);
xa = xlat_process_args(ctx, result, request, node->call.func->input_type, node->call.func->args);
if (xa == XLAT_ACTION_FAIL) {
if (RDEBUG_ENABLED2) fr_dlist_talloc_free(&result_copy);
xa = node->call.func->func.async(ctx, out, request,
node->call.inst->data, thread_inst->data, result);
- fr_dlist_verify(result);
+ VALUE_BOX_LIST_VERIFY(result);
if (RDEBUG_ENABLED2) {
xlat_debug_log_expansion(request, *in, &result_copy);
xlat_debug_log_expansion(request, *in, NULL);
xlat_debug_log_list_result(request, result);
- fr_dlist_verify(result);
+ VALUE_BOX_LIST_VERIFY(result);
fr_dcursor_init(&from, result);
fr_dcursor_merge(out, &from);
fr_assert(fr_dlist_empty(result));
node->fmt);
fr_assert(!fr_dlist_empty(result));
- fr_dlist_verify(result);
+
+ VALUE_BOX_LIST_VERIFY(result);
/*
* If the input is a series of xlat expansions,
MEM(value = fr_value_box_alloc_null(ctx));
if (!fr_dlist_empty(result)) {
- fr_dlist_verify(result);
str = fr_value_box_list_aprint(value, result, NULL, NULL);
if (!str) return XLAT_ACTION_FAIL;
} else {
fr_dlist_talloc_free(result);
fr_dlist_insert_head(result, value);
}
+ VALUE_BOX_LIST_VERIFY(result);
MEM(value = fr_value_box_alloc(ctx, FR_TYPE_GROUP, NULL, false));
fr_dlist_move(&value->vb_group, result);
* Does nothing if the list was not initialised with #fr_dlist_talloc_init.
*/
#ifndef TALLOC_GET_TYPE_ABORT_NOOP
-static inline CC_HINT(nonnull) void fr_dlist_verify(fr_dlist_head_t *list_head)
+static inline CC_HINT(nonnull) void fr_dlist_verify(char const *file, int line, fr_dlist_head_t *list_head)
{
void *item;
if (!list_head->type) return;
+ fr_assert_msg(fr_dlist_initialised(list_head), "CONSISTENCY CHECK FAILED %s[%i]: dlist not initialised",
+ file, line);
+
for (item = fr_dlist_head(list_head);
item;
item = fr_dlist_next(list_head, item)) {
item = _talloc_get_type_abort(item, list_head->type, __location__);
}
}
+# define FR_DLIST_VERIFY(_head) fr_dlist_verify(__FILE__, __LINE__, _head)
#elif !defined(NDEBUG)
-# define fr_dlist_verify(_head) fr_assert(_head)
+# define FR_DLIST_VERIFY(_head) fr_assert(_head)
#else
-# define fr_dlist_verify(_head)
+# define FR_DLIST_VERIFY(_head)
#endif
/** Merge two lists, inserting the tail of one into the other
fr_value_box_t vb;
ssize_t slen;
- memset(&vb, 0, sizeof(vb));
-
/*
* Be lazy by just converting it to a string, and then printing the string.
*/
return false;
}
+
+/** Validation function to check that a fr_value_box_t is correctly initialised
+ *
+ * @note Do not add talloc checks here. fr_value_box_t may be allocated on the stack.
+ */
+void value_box_verify(char const *file, int line, fr_value_box_t const *vb)
+{
+ fr_fatal_assert_msg(vb, "CONSISTENCY CHECK FAILED %s[%i]: fr_value_box_t pointer was NULL", file, line);
+
+ switch (vb->type) {
+ case FR_TYPE_STRING:
+ fr_fatal_assert_msg(vb->vb_strvalue, "CONSISTENCY CHECK FAILED %s[%i]: fr_value_box_t strvalue field "
+ "was NULL", file, line);
+ fr_fatal_assert_msg(vb->vb_strvalue[vb->vb_length] == '\0',
+ "CONSISTENCY CHECK FAILED %s[%i]: fr_value_box_t strvalue field "
+ "not null terminated", file, line);
+ break;
+
+ case FR_TYPE_OCTETS:
+ fr_fatal_assert_msg(vb->vb_octets, "CONSISTENCY CHECK FAILED %s[%i]: fr_value_box_t octets field "
+ "was NULL", file, line);
+ break;
+
+ case FR_TYPE_VOID:
+ fr_fatal_assert_msg(vb->vb_void, "CONSISTENCY CHECK FAILED %s[%i]: fr_value_box_t ptr field "
+ "was NULL", file, line);
+ break;
+
+ case FR_TYPE_GROUP:
+ value_box_list_verify(file, line, &vb->vb_group);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void value_box_list_verify(char const *file, int line, fr_value_box_list_t const *list)
+{
+ fr_value_box_t const *vb;
+
+ FR_DLIST_VERIFY(list);
+
+ while ((vb = fr_dlist_next(list, vb))) value_box_verify(file, line, list);
+}
*/
#define vb_strvalue datum.strvalue
#define vb_octets datum.octets
+#define vb_void datum.ptr
#define vb_group datum.children
#define vb_ip datum.ip
int fr_value_box_list_flatten_argv(TALLOC_CTX *ctx, char ***argv_p, fr_value_box_list_t const *in);
/** @} */
-/*
- * Printing
+/** @name Print the value of a value box as a string
+ *
+ * @{
*/
ssize_t fr_value_box_print(fr_sbuff_t *out, fr_value_box_t const *data, fr_sbuff_escape_rules_t const *e_rules) CC_HINT(nonnull(1,2));
{
SBUFF_OUT_TALLOC_FUNC_NO_LEN_DEF(fr_value_box_print_quoted, data, quote)
}
+/** @} */
/** @name Hashing
*
* @{
uint32_t fr_value_box_hash_update(fr_value_box_t const *vb, uint32_t hash);
/** @} */
+void value_box_verify(char const *file, int line, fr_value_box_t const *vb);
+void value_box_list_verify(char const *file, int line, fr_value_box_list_t const *list);
+
+#ifdef WITH_VERIFY_PTR
+# define VALUE_BOX_VERIFY(_x) value_box_verify(__FILE__, __LINE__, _x)
+# define VALUE_BOX_LIST_VERIFY(_x) value_box_list_verify(__FILE__, __LINE__, _x)
+#else
+/*
+ * Even if were building without WITH_VERIFY_PTR
+ * the pointer must not be NULL when these various macros are used
+ * so we can add some sneaky asserts.
+ */
+# define VALUE_BOX_VERIFY(_x) fr_assert(_x)
+# define VALUE_BOX_LIST_VERIFY(_x) fr_assert(_x)
+#endif
+
#undef _CONST
#ifdef __cplusplus