26RCSID(
"$Id: efa54e8a18513b795641ff2f17231e946e3fce24 $")
28#include <freeradius-devel/util/strerror.h>
29#include <freeradius-devel/util/regex.h>
33#define swap(_a, _b) do { __typeof__ (_a) _tmp = _a; _a = _b; _b = _tmp; } while (0)
36#define ERR_UNDERFLOW (-4)
37#define ERR_OVERFLOW (-3)
38#define ERR_INVALID (-2)
40#define COERCE(_vb, _box, _type, _enumv) do { \
41 if (_vb->type != _type) { \
42 if (fr_value_box_cast(NULL, &_box, _type, _enumv, _vb) < 0) return -1; \
40#define COERCE(_vb, _box, _type, _enumv) do { \ …
47#define COERCE_A(_type, _enumv) COERCE(a, one, _type, _enumv)
48#define COERCE_B(_type, _enumv) COERCE(b, two, _type, _enumv)
743 dst->vb_bool = a->vb_bool | b->vb_bool;
752 dst->vb_bool = a->vb_bool - b->vb_bool;
757 dst->vb_bool = a->vb_bool & b->vb_bool;
761 dst->vb_bool = a->vb_bool | b->vb_bool;
765 dst->vb_bool = a->vb_bool ^ b->vb_bool;
784 fr_strerror_const(
"Cannot perform operation on two values of type 'date'. One value must be a number.");
924 len = a->vb_length + b->vb_length;
928 buf = talloc_array(ctx,
uint8_t, len);
935 memcpy(buf, a->vb_octets, a->vb_length);
936 memcpy(buf + a->vb_length, b->vb_octets, b->vb_length);
945 if (a->vb_length < b->vb_length) {
950 if (memcmp(a->vb_octets + a->vb_length - b->vb_length, b->vb_strvalue, b->vb_length) != 0) {
955 len = a->vb_length - b->vb_length;
956 buf = talloc_array(ctx,
uint8_t, len);
959 memcpy(buf, a->vb_strvalue, len);
965 if (a->vb_length != b->vb_length) {
971 buf = talloc_array(ctx,
uint8_t, a->vb_length);
974 for (len = 0; len < a->vb_length; len++) {
975 buf[len] = a->vb_octets[len] & b->vb_octets[len];
982 if (a->vb_length != b->vb_length)
goto length_error;
984 buf = talloc_array(ctx,
uint8_t, a->vb_length);
987 for (len = 0; len < a->vb_length; len++) {
988 buf[len] = a->vb_octets[len] | b->vb_octets[len];
995 if (a->vb_length != b->vb_length)
goto length_error;
997 buf = talloc_array(ctx,
uint8_t, a->vb_length);
1000 for (len = 0; len < a->vb_length; len++) {
1001 buf[len] = a->vb_octets[len] ^ b->vb_octets[len];
1010 len = a->vb_length - b->vb_uint32;
1011 buf = talloc_array(ctx,
uint8_t, len);
1014 memcpy(buf, a->vb_octets, len);
1022 len = a->vb_length - b->vb_uint32;
1024 buf = talloc_array(ctx,
uint8_t, len);
1027 memcpy(buf, a->vb_octets + b->vb_uint32, len);
1063 len = a->vb_length + b->vb_length;
1067 buf = talloc_array(ctx,
char, len + 1);
1074 len = a->vb_length + b->vb_length;
1075 memcpy(buf, a->vb_strvalue, a->vb_length);
1076 memcpy(buf + a->vb_length, b->vb_strvalue, b->vb_length);
1083 buf = talloc_array(ctx,
char, len + 1);
1086 len = a->vb_length + b->vb_length;
1087 memcpy(buf, b->vb_strvalue, b->vb_length);
1088 memcpy(buf + b->vb_length, a->vb_strvalue, a->vb_length);
1098 if (a->vb_length < b->vb_length) {
1103 if (memcmp(a->vb_strvalue + a->vb_length - b->vb_length, b->vb_strvalue, b->vb_length) != 0) {
1108 len = a->vb_length - b->vb_length;
1109 buf = talloc_array(ctx,
char, len + 1);
1112 memcpy(buf, a->vb_strvalue, len);
1121 len = a->vb_length - b->vb_uint32;
1122 buf = talloc_array(ctx,
char, len + 1);
1125 memcpy(buf, a->vb_strvalue, len);
1134 len = a->vb_length - b->vb_uint32;
1136 buf = talloc_array(ctx,
char, len + 1);
1139 memcpy(buf, a->vb_strvalue + b->vb_uint32, len);
1167 out->vb_ip =
in->vb_ip;
1171 if (
in->vb_ip.af == AF_INET6)
goto cast_ipv6_prefix;
1174 out->vb_ip =
in->vb_ip;
1257 dst->vb_ip.af = AF_INET;
1258 dst->vb_ip.addr.v4.s_addr = htonl(ntohl(a->vb_ip.addr.v4.s_addr) | b->vb_uint32);
1259 dst->vb_ip.prefix = 32;
1308 if (b->vb_uint32 == 0) {
1309 dst->vb_ip.addr.v4.s_addr = 0;
1312 }
else if ((~b->vb_uint32) == 0) {
1313 dst->vb_ip.addr.v4.s_addr = a->vb_ip.addr.v4.s_addr;
1319 mask = ~b->vb_uint32;
1321 if ((
mask & b->vb_uint32) !=
mask) {
1329 while (prefix > 0) {
1330 if (
mask == b->vb_uint32)
break;
1338 dst->vb_ip.addr.v4.s_addr = htonl(ntohl(a->vb_ip.addr.v4.s_addr) & b->vb_uint32);
1341 dst->vb_ip.af = AF_INET;
1342 dst->vb_ip.prefix = prefix;
1364 out->vb_ip =
in->vb_ip;
1368 if (
in->vb_ip.af == AF_INET)
goto cast_ipv4_prefix;
1371 out->vb_ip =
in->vb_ip;
1459 if (b->vb_uint64 >= (((uint64_t) 1) << (128 - a->vb_ip.prefix)))
return ERR_OVERFLOW;
1464 mask = b->vb_uint64;
1465 for (i = 15; i >= ((a->vb_ip.prefix + 7) >> 3); i--) {
1466 dst->vb_ip.addr.v6.s6_addr[i] |=
mask & 0xff;
1470 dst->vb_ip.af = AF_INET6;
1471 dst->vb_ip.prefix = 0;
1472 dst->vb_ip.scope_id = a->vb_ip.scope_id;
1487 for (i = 15; i >= 0; i--) {
1493 for (j = 0; j < 8; j++) {
1494 if ((
in[i] & (1 << j)) == 0) {
1507 int i, prefix = 128;
1514 if (a->vb_length != (128 / 8)) {
1522 pa = (
const uint8_t *) &a->vb_ip.addr.v6.s6_addr;
1529 if (b->vb_length != (128 / 8)) {
1537 pb = (
const uint8_t *) &b->vb_ip.addr.v6;
1546 pdst = (
uint8_t *) &dst->vb_ip.addr.v6;
1548 for (i = 0; i < 16; i++) {
1549 pdst[i] = pa[i] & pb[i];
1552 dst->vb_ip.af = AF_INET6;
1553 dst->vb_ip.prefix = prefix;
1563#define is_ipv6(_x) (((_x)->type == FR_TYPE_IPV6_ADDR) || ((_x)->type == FR_TYPE_IPV6_PREFIX) || ((((_x)->type == FR_TYPE_COMBO_IP_ADDR) || ((_x)->type == FR_TYPE_COMBO_IP_PREFIX)) && ((_x)->vb_ip.af == AF_INET6)))
1603 dst->vb_float32 = a->vb_float64 + b->vb_float64;
1607 dst->vb_float32 = a->vb_float64 - b->vb_float64;
1611 dst->vb_float32 = a->vb_float64 * b->vb_float64;
1615 if (fpclassify(b->vb_float64) == FP_ZERO)
return ERR_ZERO;
1617 dst->vb_float32 = a->vb_float64 / b->vb_float64;
1621 if (fpclassify(b->vb_float64) == FP_ZERO)
return ERR_ZERO;
1623 dst->vb_float32 = fmod(a->vb_float64, b->vb_float64);
1647 dst->vb_float64 = a->vb_float64 + b->vb_float64;
1651 dst->vb_float64 = a->vb_float64 - b->vb_float64;
1655 dst->vb_float64 = a->vb_float64 * b->vb_float64;
1659 if (fpclassify(b->vb_float64) == FP_ZERO)
return ERR_ZERO;
1661 dst->vb_float64 = a->vb_float64 / b->vb_float64;
1665 if (fpclassify(b->vb_float64) == FP_ZERO)
return ERR_ZERO;
1667 dst->vb_float64 = fmod(a->vb_float64, b->vb_float64);
1715 if (b->vb_uint64 == 0)
return ERR_ZERO;
1717 result.vb_uint64 = a->vb_uint64 / b->vb_uint64;
1721 if (b->vb_uint64 == 0)
return ERR_ZERO;
1723 result.vb_uint64 = a->vb_uint64 % in2->vb_uint64;
1727 result.vb_uint64 = a->vb_uint64 & b->vb_uint64;
1731 result.vb_uint64 = a->vb_uint64 | b->vb_uint64;
1735 result.vb_uint64 = a->vb_uint64 ^ b->vb_uint64;
1739 if (b->vb_uint32 >= (8 *
sizeof(a->vb_uint64)))
return ERR_UNDERFLOW;
1741 result.vb_uint64 = a->vb_uint64 >> b->vb_uint32;
1745 if (b->vb_uint32 >= (8 *
sizeof(a->vb_uint64)))
return ERR_OVERFLOW;
1747 result.vb_uint64 = a->vb_uint64 << b->vb_uint32;
1799 if (b->vb_int64 == 0)
return ERR_ZERO;
1801 result.vb_int64 = a->vb_int64 / b->vb_int64;
1805 if (b->vb_int64 == 0)
return ERR_ZERO;
1807 result.vb_int64 = a->vb_int64 % in2->vb_int64;
1811 result.vb_int64 = a->vb_int64 & b->vb_int64;
1815 result.vb_int64 = a->vb_int64 | b->vb_int64;
1819 result.vb_int64 = a->vb_int64 ^ b->vb_int64;
1823 if (b->vb_uint32 >= (8 *
sizeof(a->vb_int64)))
return ERR_UNDERFLOW;
1825 result.vb_int64 = a->vb_int64 >> b->vb_uint32;
1829 if (b->vb_uint32 >= (8 *
sizeof(a->vb_int64)))
return ERR_OVERFLOW;
1831 result.vb_int64 = a->vb_int64 << b->vb_uint32;
1916 if (a->type != b->type) {
1919 dst->vb_bool =
false;
1926 if (a->type != b->type)
goto mismatch_type;
1939 if (rcode < 0)
return rcode;
1942 dst->vb_bool = (rcode != 0);
2039 }
else if (a->type != b->type) {
2100 if (a->type != b->type) {
2139 if (hint == a->type) enumv = a->enumv;
2140 if (hint == b->type) enumv = b->enumv;
2155 if (a->type != hint) {
2160 if (b->type != hint) {
2167 if (rcode < 0)
goto done;
2170 dst->vb_bool = (rcode > 0);
2214 rcode = func(ctx, &
out, a, op, b);
2215 if (rcode < 0)
goto done;
2218 dst->tainted = a->tainted | b->tainted;
2258 bool tainted =
false;
2277 bool tainted =
false;
2350 vb = fr_value_box_list_head(&group->vb_group);
2358 while ((vb = fr_value_box_list_next(&group->vb_group, vb)) != NULL) {
2362 if (vb->type ==
type) {
2363 rcode = calc(ctx, &
out, &
out, op, vb);
2364 if (rcode < 0)
return rcode;
2369 rcode = calc(ctx, &
out, &
out, op, &box);
2370 if (rcode < 0)
return rcode;
2378#define T(_x) [T_OP_ ## _x ## _EQ] = T_ ## _x
2406 if (dst->immutable) {
2419 if (src == dst)
return 0;
2445 while ((vb = fr_value_box_list_next(&src->vb_group, vb)) != NULL) {
2447 if (rcode < 0)
break;
2467 if (dst->immutable) {
2477 switch (src->type) {
2534#define COMP(_type, _field) case FR_TYPE_ ## _type: dst->vb_ ##_field = (_field ## _t) ~src->vb_ ##_field; break
2535 switch (src->type) {
2537 COMP(UINT16, uint16);
2538 COMP(UINT32, uint32);
2539 COMP(UINT64, uint64);
2553 }
else if (op ==
T_SUB) {
2569 }
else if (op ==
T_NOT) {
2574 dst->vb_bool = !
value;
2597 bool tainted =
false;
2604 if (a->type != box->type) {
2609 len += a->vb_length;
2612 if (!len)
goto brute_force;
2615 str = talloc_array(ctx,
uint8_t, len);
2616 if (!str)
return -1;
2618 str = talloc_array(ctx,
uint8_t, len + 1);
2619 if (!str)
return -1;
2626 memcpy(p, a->vb_octets, a->vb_length);
2628 tainted |= a->tainted;
2663 switch (
item->type) {
2673 if (
item->vb_length != 0)
return false;
2691 bool invert =
false;
2692 bool a_empty, b_empty;
2715 if (a_empty && b_empty) {
2736 if (rcode < 0)
return rcode;
2742 if (!dst->vb_bool)
continue;
2747 dst->vb_bool = !invert;
2758 dst->vb_bool = invert;
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
static int calc_date(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
static const fr_type_t upcast_cmp[FR_TYPE_MAX+1][FR_TYPE_MAX+1]
Updates type (a,b) -> c.
static int calc_ipv4_addr(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
static int get_ipv6_prefix(uint8_t const *in)
static const fr_binary_op_t calc_type[FR_TYPE_MAX+1]
Map output type to its associated function.
static int calc_ipv6_addr(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
static int invalid_type(fr_type_t type)
static const fr_type_t upcast_op[FR_TYPE_MAX+1][FR_TYPE_MAX+1]
Updates type (a,b) -> c.
static int calc_float32(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
#define COERCE_A(_type, _enumv)
static int calc_ipv4_prefix(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
static const fr_type_t upcast_unsigned[FR_TYPE_MAX+1]
static int calc_uint64(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
static int calc_octets(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
static int calc_combo_ip_addr(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
static int calc_ipv6_prefix(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
static int cast_ipv6_addr(fr_value_box_t *out, fr_value_box_t const *in)
static int handle_result(fr_type_t type, fr_token_t op, int rcode)
static int calc_int64(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
static int calc_bool(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
static int calc_string(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
int fr_value_calc_list_cmp(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_list_t const *list1, fr_token_t op, fr_value_box_list_t const *list2)
int fr_value_calc_list_op(TALLOC_CTX *ctx, fr_value_box_t *box, fr_token_t op, fr_value_box_list_t const *list)
Apply a set of operations in order to create an output box.
static int calc_combo_ip_prefix(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
static int calc_time_delta(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
int(* fr_binary_op_t)(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
static int cast_ipv4_addr(fr_value_box_t *out, fr_value_box_t const *in)
static bool fr_value_calc_list_empty(fr_value_box_list_t const *list)
static int calc_float64(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2)
int fr_value_calc_nary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t type, fr_token_t op, fr_value_box_t const *group)
Calculate DST = OP { A, B, C, ... }.
#define COERCE_B(_type, _enumv)
static const fr_token_t assignment2op[T_TOKEN_LAST]
int fr_value_calc_assignment_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_token_t op, fr_value_box_t const *src)
Calculate DST OP SRC.
int fr_value_calc_binary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t hint, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
Calculate DST = A OP B.
#define COMP(_type, _field)
int fr_value_calc_unary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_token_t op, fr_value_box_t const *src)
Calculate unary operations.
#define fr_dbuff_used(_dbuff_or_marker)
Return the number of bytes remaining between the start of the dbuff or marker and the current positio...
#define fr_dbuff_start(_dbuff_or_marker)
Return the 'start' position of a dbuff or marker.
#define FR_DBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max)
Create a function local and thread local extensible dbuff.
static void * item(fr_lst_t const *lst, fr_lst_index_t idx)
#define fr_sub(_out, _a, _b)
Subtracts two integers.
#define fr_add(_out, _a, _b)
Adds two integers.
#define fr_multiply(_out, _a, _b)
Multiplies two integers together.
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
@ FR_TYPE_FLOAT32
Single precision floating point.
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_INT8
8 Bit signed integer.
@ FR_TYPE_ETHERNET
48 Bit Mac-Address.
@ FR_TYPE_IPV6_PREFIX
IPv6 Prefix.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_MAX
Number of defined data types.
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_INT64
64 Bit signed integer.
@ FR_TYPE_INT16
16 Bit signed integer.
@ FR_TYPE_DATE
Unix time stamp, always has value >2^31.
@ FR_TYPE_COMBO_IP_PREFIX
IPv4 or IPv6 address prefix depending on length.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_INT32
32 Bit signed integer.
@ FR_TYPE_UINT64
64 Bit unsigned integer.
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
@ FR_TYPE_IPV4_PREFIX
IPv4 Prefix.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_SIZE
Unsigned integer capable of representing any memory address on the local system.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
@ FR_TYPE_IFID
Interface ID.
@ FR_TYPE_OCTETS
Raw octets.
@ FR_TYPE_GROUP
A grouping of other attributes.
@ FR_TYPE_FLOAT64
Double precision floating point.
#define fr_sbuff_start(_sbuff_or_marker)
#define fr_sbuff_used(_sbuff_or_marker)
#define FR_SBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max)
fr_aka_sim_id_type_t type
static int64_t fr_time_delta_unwrap(fr_time_delta_t time)
#define fr_time_delta_wrap(_time)
#define fr_time_delta_ispos(_a)
static fr_unix_time_t fr_unix_time_from_integer(bool *overflow, int64_t integer, fr_time_res_t res)
static uint64_t fr_unix_time_unwrap(fr_unix_time_t time)
char const * fr_tokens[T_TOKEN_LAST]
int fr_regex_cmp_op(fr_token_t op, fr_value_box_t const *a, fr_value_box_t const *b)
Compare two boxes using an operator.
char const * fr_strerror(void)
Get the last library error.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
#define fr_type_is_variable_size(_x)
#define fr_type_is_structural(_x)
#define fr_type_is_numeric(_x)
#define fr_type_is_signed(_x)
#define fr_type_is_leaf(_x)
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
#define fr_type_is_integer(_x)
ssize_t fr_value_box_list_concat_as_octets(bool *tainted, bool *secret, fr_dbuff_t *dbuff, fr_value_box_list_t *list, uint8_t const *sep, size_t sep_len, fr_value_box_list_action_t proc_action, bool flatten)
Concatenate a list of value boxes together.
int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert one type of fr_value_box_t to another.
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
int fr_value_box_cmp_op(fr_token_t op, fr_value_box_t const *a, fr_value_box_t const *b)
Compare two attributes using an operator.
bool fr_value_box_is_truthy(fr_value_box_t const *in)
Check truthiness of values.
void fr_value_box_memdup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, uint8_t const *src, size_t len, bool tainted)
Assign a buffer to a box, but don't copy it.
void fr_value_box_copy_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *src)
Perform a shallow copy of a value_box.
void fr_value_box_clear_value(fr_value_box_t *data)
Clear/free any existing value.
ssize_t fr_value_box_list_concat_as_string(bool *tainted, bool *secret, fr_sbuff_t *sbuff, fr_value_box_list_t *list, char const *sep, size_t sep_len, fr_sbuff_escape_rules_t const *e_rules, fr_value_box_list_action_t proc_action, fr_value_box_safe_for_t safe_for, bool flatten)
Concatenate a list of value boxes together.
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
int fr_value_box_bstrndup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Copy a string to to a fr_value_box_t.
void fr_value_box_bstrndup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Assign a string to to a fr_value_box_t.
int fr_value_box_memdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, uint8_t const *src, size_t len, bool tainted)
Copy a buffer to a fr_value_box_t.
@ FR_VALUE_BOX_LIST_NONE
Do nothing to processed boxes.
static void fr_value_box_set_secret(fr_value_box_t *box, bool secret)
#define fr_value_box_init_null(_vb)
Initialise an empty/null box that will be filled later.
#define fr_value_box_init(_vb, _type, _enumv, _tainted)
Initialise a fr_value_box_t.
#define fr_value_box_list_foreach(_list_head, _iter)
static size_t char ** out