26RCSID(
"$Id: 51ce99633871f7ed8e785139d9ca67c0da7e1816 $")
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; \
43 fr_value_box_safety_copy(&_box, _vb); \
48#define COERCE_A(_type, _enumv) COERCE(a, one, _type, _enumv)
49#define COERCE_B(_type, _enumv) COERCE(b, two, _type, _enumv)
744 dst->vb_bool = a->vb_bool | b->vb_bool;
753 dst->vb_bool = a->vb_bool - b->vb_bool;
758 dst->vb_bool = a->vb_bool & b->vb_bool;
762 dst->vb_bool = a->vb_bool | b->vb_bool;
766 dst->vb_bool = a->vb_bool ^ b->vb_bool;
785 fr_strerror_const(
"Cannot perform operation on two values of type 'date'. One value must be a number.");
914#ifdef __clang_analyzer__
920 if (!a->vb_octets)
return -1;
929 }
else if (op ==
T_MUL) {
936#ifdef __clang_analyzer__
937 if (!b->vb_octets)
return -1;
941 len = a->vb_length + b->vb_length;
952 memcpy(buf, a->vb_octets, a->vb_length);
953 memcpy(buf + a->vb_length, b->vb_octets, b->vb_length);
964 if (a->vb_length < b->vb_length) {
969 if (memcmp(a->vb_octets + a->vb_length - b->vb_length, b->vb_strvalue, b->vb_length) != 0) {
974 len = a->vb_length - b->vb_length;
978 memcpy(buf, a->vb_strvalue,
len);
985 if (a->vb_length != b->vb_length) {
991 buf = talloc_array(ctx,
uint8_t, a->vb_length);
994 for (
len = 0;
len < a->vb_length;
len++) {
995 buf[
len] = a->vb_octets[
len] & b->vb_octets[
len];
1005 if (a->vb_length != b->vb_length)
goto length_error;
1007 buf = talloc_array(ctx,
uint8_t, a->vb_length);
1010 for (
len = 0;
len < a->vb_length;
len++) {
1011 buf[
len] = a->vb_octets[
len] | b->vb_octets[
len];
1016 if (a->vb_length != b->vb_length)
goto length_error;
1018 buf = talloc_array(ctx,
uint8_t, a->vb_length);
1021 for (
len = 0;
len < a->vb_length;
len++) {
1022 buf[
len] = a->vb_octets[
len] ^ b->vb_octets[
len];
1030 len = a->vb_length - b->vb_uint32;
1034 memcpy(buf, a->vb_octets,
len);
1043 len = a->vb_length - b->vb_uint32;
1048 memcpy(buf, a->vb_octets + b->vb_uint32,
len);
1058 if (!b->vb_uint64 || !a->vb_length) {
1067 len = a->vb_length * b->vb_uint64;
1072 for (i = 0, p = buf; i < b->vb_uint64; i++, p += a->vb_length) {
1073 memcpy(p, a->vb_octets, a->vb_length);
1100#ifdef __clang_analyzer__
1106 if (!a->vb_strvalue)
return -1;
1115 }
else if (op ==
T_MUL) {
1122#ifdef __clang_analyzer__
1123 if (!b->vb_strvalue)
return -1;
1127 len = a->vb_length + b->vb_length;
1131 buf = talloc_array(ctx,
char,
len + 1);
1138 len = a->vb_length + b->vb_length;
1139 memcpy(buf, a->vb_strvalue, a->vb_length);
1140 memcpy(buf + a->vb_length, b->vb_strvalue, b->vb_length);
1149 buf = talloc_array(ctx,
char,
len + 1);
1152 len = a->vb_length + b->vb_length;
1153 memcpy(buf, b->vb_strvalue, b->vb_length);
1154 memcpy(buf + b->vb_length, a->vb_strvalue, a->vb_length);
1166 if (a->vb_length < b->vb_length) {
1171 if (memcmp(a->vb_strvalue + a->vb_length - b->vb_length, b->vb_strvalue, b->vb_length) != 0) {
1172 fr_strerror_const(
"Right side of substract is not a suffix of the input string");
1176 len = a->vb_length - b->vb_length;
1177 buf = talloc_array(ctx,
char,
len + 1);
1180 memcpy(buf, a->vb_strvalue,
len);
1190 len = a->vb_length - b->vb_uint32;
1191 buf = talloc_array(ctx,
char,
len + 1);
1194 memcpy(buf, a->vb_strvalue,
len);
1204 len = a->vb_length - b->vb_uint32;
1206 buf = talloc_array(ctx,
char,
len + 1);
1209 memcpy(buf, a->vb_strvalue + b->vb_uint32,
len);
1220 if (!b->vb_uint64 || !a->vb_length) {
1229 len = a->vb_length * b->vb_uint64;
1231 buf = talloc_array(ctx,
char,
len + 1);
1234 for (i = 0, p = buf; i < b->vb_uint64; i++, p += a->vb_length) {
1235 memcpy(p, a->vb_strvalue, a->vb_length);
1265 out->vb_ip =
in->vb_ip;
1269 if (
in->vb_ip.af == AF_INET6)
goto cast_ipv6_prefix;
1272 out->vb_ip =
in->vb_ip;
1355 dst->vb_ip.af = AF_INET;
1356 dst->vb_ipv4addr = htonl(ntohl(a->vb_ipv4addr) | b->vb_uint32);
1357 dst->vb_ip.prefix = 32;
1410 if (b->vb_uint32 == 0) {
1411 dst->vb_ipv4addr = 0;
1414 }
else if ((~b->vb_uint32) == 0) {
1415 dst->vb_ipv4addr = a->vb_ipv4addr;
1421 mask = ~b->vb_uint32;
1423 if ((
mask & b->vb_uint32) !=
mask) {
1431 while (prefix > 0) {
1432 if (
mask == b->vb_uint32)
break;
1439 dst->vb_ipv4addr = htonl(ntohl(a->vb_ipv4addr) & b->vb_uint32);
1442 dst->vb_ip.af = AF_INET;
1443 dst->vb_ip.prefix = prefix;
1466 out->vb_ip =
in->vb_ip;
1470 if (
in->vb_ip.af == AF_INET)
goto cast_ipv4_prefix;
1474 out->vb_ip =
in->vb_ip;
1563 if (b->vb_uint64 >= (((uint64_t) 1) << (128 - a->vb_ip.prefix)))
return ERR_OVERFLOW;
1568 memcpy(&dst->vb_ipv6addr, a->vb_ipv6addr,
sizeof(dst->vb_ipv6addr));
1569 mask = b->vb_uint64;
1570 for (i = 15; i >= ((a->vb_ip.prefix + 7) >> 3); i--) {
1571 dst->vb_ipv6addr[i] |=
mask & 0xff;
1575 dst->vb_ip.af = AF_INET6;
1576 dst->vb_ip.prefix = 128;
1577 dst->vb_ip.scope_id = a->vb_ip.scope_id;
1593 for (i = 15; i >= 0; i--) {
1599 for (j = 0; j < 8; j++) {
1600 if ((
in[i] & (1 << j)) == 0) {
1613 int i, prefix = 128;
1620 if (a->vb_length != (128 / 8)) {
1628 pa = (
const uint8_t *) &a->vb_ipv6addr;
1635 if (b->vb_length != (128 / 8)) {
1643 pb = (
const uint8_t *) &b->vb_ip.addr.v6;
1652 pdst = (
uint8_t *) &dst->vb_ip.addr.v6;
1654 for (i = 0; i < 16; i++) {
1655 pdst[i] = pa[i] & pb[i];
1658 dst->vb_ip.af = AF_INET6;
1659 dst->vb_ip.prefix = prefix;
1671#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)))
1711 dst->vb_float32 = a->vb_float64 + b->vb_float64;
1715 dst->vb_float32 = a->vb_float64 - b->vb_float64;
1719 dst->vb_float32 = a->vb_float64 * b->vb_float64;
1723 if (fpclassify(b->vb_float64) == FP_ZERO)
return ERR_ZERO;
1725 dst->vb_float32 = a->vb_float64 / b->vb_float64;
1729 if (fpclassify(b->vb_float64) == FP_ZERO)
return ERR_ZERO;
1731 dst->vb_float32 = fmod(a->vb_float64, b->vb_float64);
1758 dst->vb_float64 = a->vb_float64 + b->vb_float64;
1762 dst->vb_float64 = a->vb_float64 - b->vb_float64;
1766 dst->vb_float64 = a->vb_float64 * b->vb_float64;
1770 if (fpclassify(b->vb_float64) == FP_ZERO)
return ERR_ZERO;
1772 dst->vb_float64 = a->vb_float64 / b->vb_float64;
1776 if (fpclassify(b->vb_float64) == FP_ZERO)
return ERR_ZERO;
1778 dst->vb_float64 = fmod(a->vb_float64, b->vb_float64);
1828 if (b->vb_uint64 == 0)
return ERR_ZERO;
1830 result.vb_uint64 = a->vb_uint64 / b->vb_uint64;
1834 if (b->vb_uint64 == 0)
return ERR_ZERO;
1836 result.vb_uint64 = a->vb_uint64 % b->vb_uint64;
1840 result.vb_uint64 = a->vb_uint64 & b->vb_uint64;
1844 result.vb_uint64 = a->vb_uint64 | b->vb_uint64;
1848 result.vb_uint64 = a->vb_uint64 ^ b->vb_uint64;
1852 if (b->vb_uint32 >= (8 *
sizeof(a->vb_uint64)))
return ERR_UNDERFLOW;
1854 result.vb_uint64 = a->vb_uint64 >> b->vb_uint32;
1858 if (b->vb_uint32 >= (8 *
sizeof(a->vb_uint64)))
return ERR_OVERFLOW;
1860 result.vb_uint64 = a->vb_uint64 << b->vb_uint32;
1915 if (b->vb_int64 == 0)
return ERR_ZERO;
1917 result.vb_int64 = a->vb_int64 / b->vb_int64;
1921 if (b->vb_int64 == 0)
return ERR_ZERO;
1923 result.vb_int64 = a->vb_int64 % b->vb_int64;
1927 result.vb_int64 = a->vb_int64 & b->vb_int64;
1931 result.vb_int64 = a->vb_int64 | b->vb_int64;
1935 result.vb_int64 = a->vb_int64 ^ b->vb_int64;
1939 if (b->vb_uint32 >= (8 *
sizeof(a->vb_int64)))
return ERR_UNDERFLOW;
1941 result.vb_int64 = a->vb_int64 >> b->vb_uint32;
1945 if (b->vb_uint32 >= (8 *
sizeof(a->vb_int64)))
return ERR_OVERFLOW;
1947 result.vb_int64 = a->vb_int64 << b->vb_uint32;
2038 if (a->type != b->type) {
2041 dst->vb_bool =
false;
2048 if (a->type != b->type)
goto mismatch_type;
2061 if (rcode < 0)
return rcode;
2064 dst->vb_bool = (rcode != 0);
2171 }
else if (a->type != b->type) {
2232 if (a->type != b->type) {
2271 if (hint == a->type) enumv = a->enumv;
2272 if (hint == b->type) enumv = b->enumv;
2287 if (a->type != hint) {
2293 if (b->type != hint) {
2301 if (rcode < 0)
goto done;
2304 dst->vb_bool = (rcode > 0);
2347 rcode = func(ctx, &
out, a, op, b);
2348 if (rcode < 0)
goto done;
2351 dst->tainted = a->tainted | b->tainted;
2478 vb = fr_value_box_list_head(&group->vb_group);
2486 while ((vb = fr_value_box_list_next(&group->vb_group, vb)) != NULL) {
2490 if (vb->type ==
type) {
2491 rcode = calc(ctx, &
out, &
out, op, vb);
2492 if (rcode < 0)
return rcode;
2497 rcode = calc(ctx, &
out, &
out, op, &box);
2498 if (rcode < 0)
return rcode;
2506#define T(_x) [T_OP_ ## _x ## _EQ] = T_ ## _x
2534 if (dst->immutable) {
2547 if (src == dst)
return 0;
2573 while ((vb = fr_value_box_list_next(&src->vb_group, vb)) != NULL) {
2575 if (rcode < 0)
break;
2595 if (dst->immutable) {
2605 switch (src->type) {
2665#define COMP(_type, _field) case FR_TYPE_ ## _type: dst->vb_ ##_field = (_field ## _t) ~src->vb_ ##_field; break
2666 switch (src->type) {
2668 COMP(UINT16, uint16);
2669 COMP(UINT32, uint32);
2670 COMP(UINT64, uint64);
2684 }
else if (op ==
T_SUB) {
2700 }
else if (op ==
T_NOT) {
2705 dst->vb_bool = !
value;
2729 switch (
item->type) {
2739 if (
item->vb_length != 0)
return false;
2757 bool invert =
false;
2758 bool a_empty, b_empty;
2786 if (a_empty && b_empty) {
2807 if (rcode < 0)
return rcode;
2813 if (!dst->vb_bool)
continue;
2818 dst->vb_bool = !invert;
2829 dst->vb_bool = invert;
static uint8_t overflow[100]
#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)
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]
const bool fr_comparison_op[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.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const_push(_msg)
#define fr_strerror_const(_msg)
#define fr_type_is_structural(_x)
#define fr_type_is_integer_except_bool(_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)
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.
ssize_t fr_value_box_list_concat_as_octets(fr_value_box_safety_t *safety, 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_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.
int fr_value_box_strdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Copy a nul terminated string to a fr_value_box_t.
void fr_value_box_safety_set(fr_value_box_t *box, fr_value_box_safety_t const *safety)
Replace the safety of a box.
ssize_t fr_value_box_list_concat_as_string(fr_value_box_safety_t *safety, 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_safety_merge(fr_value_box_t *out, fr_value_box_t const *in)
Merge safety results.
void fr_value_box_safety_copy(fr_value_box_t *out, fr_value_box_t const *in)
Copy the safety values from one box to another.
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 fr_sbuff_err_t char size_t fr_sbuff_t * in
fr_value_box_safe_for_t safe_for
A unique value to indicate if that value box is safe for consumption by a particular module for a par...
#define fr_value_box_init_null(_vb)
Initialise an empty/null box that will be filled later.
static fr_sbuff_err_t char ** out
static fr_sbuff_err_t char size_t * len
#define VALUE_BOX_VERIFY(_x)
#define fr_value_box_init(_vb, _type, _enumv, _tainted)
Initialise a fr_value_box_t.
#define fr_value_box_list_foreach(_list_head, _iter)
#define FR_VALUE_BOX_SAFE_FOR_ANY