From: Arran Cudbard-Bell Date: Mon, 25 Oct 2021 18:21:06 +0000 (-0400) Subject: Convert fixed width type conversion sbuff functions to return a fr_slen_t X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c01f11c0aacb9612ed3a37c8424368b7a4e883ab;p=thirdparty%2Ffreeradius-server.git Convert fixed width type conversion sbuff functions to return a fr_slen_t --- diff --git a/src/lib/server/tmpl_tokenize.c b/src/lib/server/tmpl_tokenize.c index 24a6acd8445..26222f30ae3 100644 --- a/src/lib/server/tmpl_tokenize.c +++ b/src/lib/server/tmpl_tokenize.c @@ -1130,7 +1130,7 @@ static tmpl_attr_filter_t tmpl_attr_parse_filter(tmpl_attr_error_t *err, tmpl_at fr_sbuff_parse_error_t sberr = FR_SBUFF_PARSE_OK; fr_sbuff_t tmp = FR_SBUFF(name); - if (fr_sbuff_out(&sberr, &ar->num, &tmp) == 0) { + if (fr_sbuff_out(&sberr, &ar->num, &tmp) < 0) { if (sberr == FR_SBUFF_PARSE_ERROR_NOT_FOUND) { fr_strerror_const("Invalid array index"); if (err) *err = TMPL_ATTR_ERROR_INVALID_ARRAY_INDEX; @@ -2035,7 +2035,7 @@ static ssize_t tmpl_afrom_bool_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t bool a_bool; tmpl_t *vpt; - if (!fr_sbuff_out(NULL, &a_bool, &our_in)) { + if (fr_sbuff_out(NULL, &a_bool, &our_in) < 0) { fr_strerror_const("Not a boolean value"); return 0; } @@ -2151,7 +2151,7 @@ static ssize_t tmpl_afrom_ipv4_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t * an IP prefix. */ if (fr_sbuff_next_if_char(&our_in, '/')) { - if (!fr_sbuff_out(NULL, &octet, &our_in)) { + if (fr_sbuff_out(NULL, &octet, &our_in) < 0) { fr_strerror_const("IPv4 CIDR mask malformed"); goto error; } @@ -2268,7 +2268,7 @@ static ssize_t tmpl_afrom_ipv6_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t if (fr_sbuff_next_if_char(&our_in, '/')) { uint8_t mask; - if (!fr_sbuff_out(NULL, &mask, &our_in)) { + if (fr_sbuff_out(NULL, &mask, &our_in) < 0) { fr_strerror_const("IPv6 CIDR mask malformed"); goto error; } diff --git a/src/lib/util/sbuff.c b/src/lib/util/sbuff.c index eae7cc5f6f9..c39c8fcd914 100644 --- a/src/lib/util/sbuff.c +++ b/src/lib/util/sbuff.c @@ -35,8 +35,10 @@ static_assert(sizeof(unsigned long long) >= sizeof(uint64_t), "long long must be fr_table_num_ordered_t const sbuff_parse_error_table[] = { { L("ok"), FR_SBUFF_PARSE_OK }, { L("token not found"), FR_SBUFF_PARSE_ERROR_NOT_FOUND }, + { L("token format invalid"), FR_SBUFF_PARSE_ERROR_FORMAT }, + { L("out of space"), FR_SBUFF_PARSE_ERROR_OUT_OF_SPACE }, { L("integer overflow"), FR_SBUFF_PARSE_ERROR_NUM_OVERFLOW }, - { L("integer underflow"), FR_SBUFF_PARSE_ERROR_NUM_UNDERFLOW }, + { L("integer underflow"), FR_SBUFF_PARSE_ERROR_NUM_UNDERFLOW } }; size_t sbuff_parse_error_table_len = NUM_ELEMENTS(sbuff_parse_error_table); @@ -996,58 +998,60 @@ done: * @param[out] out Where to write boolean value. * @param[in] in Where to search for a truth value. * @return - * - 0 no bytes copied. Was not a truth value. * - >0 the number of bytes consumed. + * - -1 no bytes copied, was not a truth value. */ -size_t fr_sbuff_out_bool(bool *out, fr_sbuff_t *in) +fr_slen_t fr_sbuff_out_bool(bool *out, fr_sbuff_t *in) { + fr_sbuff_t our_in = FR_SBUFF(in); + static bool const bool_prefix[UINT8_MAX + 1] = { ['t'] = true, ['T'] = true, /* true */ ['f'] = true, ['F'] = true, /* false */ ['y'] = true, ['Y'] = true, /* yes */ - ['n'] = true, ['N'] = true /* no */ + ['n'] = true, ['N'] = true, /* no */ }; -#define IS_TOKEN(_t) ((fr_sbuff_extend_lowat(NULL, in, sizeof(_t) - 1) >= (sizeof(_t) - 1)) && \ - (strncasecmp(in->p, _t, sizeof(_t) - 1) == 0)) - - if (fr_sbuff_is_in_charset(in, bool_prefix)) { - switch (tolower(*in->p)) { + if (fr_sbuff_is_in_charset(&our_in, bool_prefix)) { + switch (tolower(*fr_sbuff_current(&our_in))) { default: break; case 't': - if (IS_TOKEN("true")) { + if (fr_sbuff_adv_past_strcase_literal(&our_in, "true")) { *out = true; - return fr_sbuff_advance(in, sizeof("true") - 1); + return fr_sbuff_set(in, &our_in); } break; case 'f': - if (IS_TOKEN("false")) { + if (fr_sbuff_adv_past_strcase_literal(&our_in, "false")) { *out = false; - return fr_sbuff_advance(in, sizeof("false") - 1); + return fr_sbuff_set(in, &our_in); } break; case 'y': - if (IS_TOKEN("yes")) { + if (fr_sbuff_adv_past_strcase_literal(&our_in, "yes")) { *out = true; - return fr_sbuff_advance(in, sizeof("yes") - 1); + return fr_sbuff_set(in, &our_in); } break; case 'n': - if (IS_TOKEN("no")) { + if (fr_sbuff_adv_past_strcase_literal(&our_in, "no")) { *out = false; - return fr_sbuff_advance(in, sizeof("no") - 1); + return fr_sbuff_set(in, &our_in); } break; } } *out = false; /* Always initialise out */ - return 0; + + fr_strerror_const("Not a valid boolean value. Accepted values are 'yes', 'no', 'true', 'false'"); + + return -1; } /** Used to define a number parsing functions for singed integers @@ -1061,7 +1065,7 @@ size_t fr_sbuff_out_bool(bool *out, fr_sbuff_t *in) * used in . */ #define SBUFF_PARSE_INT_DEF(_name, _type, _min, _max, _max_char) \ -size_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t *in, bool no_trailing) \ +fr_slen_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t *in, bool no_trailing) \ { \ char buff[_max_char + 1]; \ char *end, *a_end; \ @@ -1071,28 +1075,28 @@ size_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t len = fr_sbuff_out_bstrncpy(&FR_SBUFF_IN(buff, sizeof(buff)), &our_in, _max_char); \ if (len == 0) { \ if (err) *err = FR_SBUFF_PARSE_ERROR_NOT_FOUND; \ - return 0; \ + return -1; \ } \ num = strtoll(buff, &end, 10); \ if (end == buff) { \ if (err) *err = FR_SBUFF_PARSE_ERROR_NOT_FOUND; \ - return 0; \ + return -1; \ } \ if ((num > (_max)) || ((errno == EINVAL) && (num == LLONG_MAX))) { \ if (err) *err = FR_SBUFF_PARSE_ERROR_NUM_OVERFLOW; \ *out = (_type)(_max); \ - return 0; \ + return -1; \ } else if (no_trailing && (((a_end = in->p + (end - buff)) + 1) < in->end)) { \ if (isdigit(*a_end)) { \ if (err) *err = FR_SBUFF_PARSE_ERROR_TRAILING; \ *out = (_type)(_max); \ - return 0; \ + return fr_sbuff_error(&our_in); \ } \ *out = (_type)(num); \ } else if (num < (_min) || ((errno == EINVAL) && (num == LLONG_MIN))) { \ if (err) *err = FR_SBUFF_PARSE_ERROR_NUM_UNDERFLOW; \ *out = (_type)(_min); \ - return 0; \ + return -1; \ } else { \ if (err) *err = FR_SBUFF_PARSE_OK; \ *out = (_type)(num); \ @@ -1104,6 +1108,7 @@ SBUFF_PARSE_INT_DEF(int8, int8_t, INT8_MIN, INT8_MAX, 4) SBUFF_PARSE_INT_DEF(int16, int16_t, INT16_MIN, INT16_MAX, 6) SBUFF_PARSE_INT_DEF(int32, int32_t, INT32_MIN, INT32_MAX, 11) SBUFF_PARSE_INT_DEF(int64, int64_t, INT64_MIN, INT64_MAX, 20) +SBUFF_PARSE_INT_DEF(ssize, ssize_t, SSIZE_MIN, SSIZE_MAX, 20) /** Used to define a number parsing functions for singed integers * @@ -1116,7 +1121,7 @@ SBUFF_PARSE_INT_DEF(int64, int64_t, INT64_MIN, INT64_MAX, 20) * @param[in] _base of the number being parsed, 8, 10, 18 etc... */ #define SBUFF_PARSE_UINT_DEF(_name, _type, _max, _max_char, _base) \ -size_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t *in, bool no_trailing) \ +fr_slen_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t *in, bool no_trailing) \ { \ char buff[_max_char + 1]; \ char *end, *a_end; \ @@ -1126,22 +1131,22 @@ size_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t len = fr_sbuff_out_bstrncpy(&FR_SBUFF_IN(buff, sizeof(buff)), &our_in, _max_char); \ if (len == 0) { \ if (err) *err = FR_SBUFF_PARSE_ERROR_NOT_FOUND; \ - return 0; \ + return -1; \ } \ num = strtoull(buff, &end, _base); \ if (end == buff) { \ if (err) *err = FR_SBUFF_PARSE_ERROR_NOT_FOUND; \ - return 0; \ + return -1; \ } \ if ((num > (_max)) || ((errno == EINVAL) && (num == ULLONG_MAX))) { \ if (err) *err = FR_SBUFF_PARSE_ERROR_NUM_OVERFLOW; \ *out = (_type)(_max); \ - return 0; \ + return -1; \ } else if (no_trailing && (((a_end = in->p + (end - buff)) + 1) < in->end)) { \ if (isdigit(*a_end) || ((_base > 10) && ((tolower(*a_end) >= 'a') && (tolower(*a_end) <= 'f')))) { \ if (err) *err = FR_SBUFF_PARSE_ERROR_TRAILING; \ *out = (_type)(_max); \ - return 0; \ + return fr_sbuff_error(&our_in); \ } \ if (err) *err = FR_SBUFF_PARSE_OK; \ *out = (_type)(num); \ @@ -1156,16 +1161,19 @@ SBUFF_PARSE_UINT_DEF(uint8, uint8_t, UINT8_MAX, 3, 10) SBUFF_PARSE_UINT_DEF(uint16, uint16_t, UINT16_MAX, 4, 10) SBUFF_PARSE_UINT_DEF(uint32, uint32_t, UINT32_MAX, 10, 10) SBUFF_PARSE_UINT_DEF(uint64, uint64_t, UINT64_MAX, 19, 10) +SBUFF_PARSE_UINT_DEF(size, size_t, SIZE_MAX, 19, 10) SBUFF_PARSE_UINT_DEF(uint8_oct, uint8_t, UINT8_MAX, 3, 8) SBUFF_PARSE_UINT_DEF(uint16_oct, uint16_t, UINT16_MAX, 6, 8) SBUFF_PARSE_UINT_DEF(uint32_oct, uint32_t, UINT32_MAX, 11, 8) SBUFF_PARSE_UINT_DEF(uint64_oct, uint64_t, UINT64_MAX, 22, 8) +SBUFF_PARSE_UINT_DEF(size_oct, size_t, SIZE_MAX, 22, 8) SBUFF_PARSE_UINT_DEF(uint8_hex, uint8_t, UINT8_MAX, 2, 16) SBUFF_PARSE_UINT_DEF(uint16_hex, uint16_t, UINT16_MAX, 4, 16) SBUFF_PARSE_UINT_DEF(uint32_hex, uint32_t, UINT32_MAX, 8, 16) SBUFF_PARSE_UINT_DEF(uint64_hex, uint64_t, UINT64_MAX, 16, 16) +SBUFF_PARSE_UINT_DEF(size_hex, size_t, SIZE_MAX, 22, 16) /** Used to define a number parsing functions for floats * @@ -1177,7 +1185,7 @@ SBUFF_PARSE_UINT_DEF(uint64_hex, uint64_t, UINT64_MAX, 16, 16) * used in . */ #define SBUFF_PARSE_FLOAT_DEF(_name, _type, _func, _max_char) \ -size_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t *in, bool no_trailing) \ +fr_slen_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t *in, bool no_trailing) \ { \ char buff[_max_char + 1]; \ char *end; \ @@ -1187,20 +1195,24 @@ size_t fr_sbuff_out_##_name(fr_sbuff_parse_error_t *err, _type *out, fr_sbuff_t len = fr_sbuff_out_bstrncpy_allowed(&FR_SBUFF_OUT(buff, sizeof(buff)), &our_in, SIZE_MAX, sbuff_char_class_float); \ if (len == sizeof(buff)) { \ if (err) *err = FR_SBUFF_PARSE_ERROR_NOT_FOUND; \ - return 0; \ + return -1; \ } else if (len == 0) { \ if (err) *err = FR_SBUFF_PARSE_ERROR_NOT_FOUND; \ - return 0; \ + return -1; \ } \ res = _func(buff, &end); \ if (errno == ERANGE) { \ - if (err) *err = ((res > 0) ? FR_SBUFF_PARSE_ERROR_NUM_OVERFLOW : FR_SBUFF_PARSE_ERROR_NUM_UNDERFLOW); \ - return 0; \ + if (res > 0) { \ + if (err) *err = FR_SBUFF_PARSE_ERROR_NUM_OVERFLOW; \ + } else { \ + if (err) *err = FR_SBUFF_PARSE_ERROR_NUM_UNDERFLOW; \ + } \ + return -1; \ } \ if (no_trailing && (*end != '\0')) { \ if (err) *err = FR_SBUFF_PARSE_ERROR_TRAILING; \ *out = res; \ - return 0; \ + return fr_sbuff_error(&our_in); \ } \ return fr_sbuff_advance(in, end - buff); \ } diff --git a/src/lib/util/sbuff.h b/src/lib/util/sbuff.h index bd2eb5e82b4..8780d8e3d20 100644 --- a/src/lib/util/sbuff.h +++ b/src/lib/util/sbuff.h @@ -42,6 +42,17 @@ extern "C" { #include #include +/** Represents number of bytes parsed or location of parse error + * + * Number of bytes parsed will be >= 0. + * + * If a parse error occurs the value will be the negative offset + * of the error -1. i.e. offset 0 will be -1. + * + * This is to disambiguate between 0 bytes parsed and error at + * offset 0. + */ +typedef ssize_t fr_slen_t; typedef struct fr_sbuff_s fr_sbuff_t; typedef struct fr_sbuff_ptr_s fr_sbuff_marker_t; @@ -806,6 +817,15 @@ static inline fr_sbuff_t *fr_sbuff_init_talloc(TALLOC_CTX *ctx, ((size_t)(fr_sbuff_start(_sbuff_or_marker) > fr_sbuff_current(_sbuff_or_marker) ? \ 0 : (fr_sbuff_current(_sbuff_or_marker) - fr_sbuff_start(_sbuff_or_marker)))) +/** Return the current position as an error marker + * + * +1 is added to the position to disambiguate with 0 meaning "parsed no data". + * + * An error at offset 0 will be returned as -1. + */ +#define fr_sbuff_error(_sbuff_or_marker) \ + (-(fr_sbuff_used(_sbuff_or_marker) + 1)) + /** Like fr_sbuff_used, but adjusts for the value returned for the amount shifted * * @param[in] _sbuff_or_marker to return the number of bytes used for. @@ -1427,29 +1447,33 @@ SBUFF_OUT_TALLOC_FUNC_DEF(fr_sbuff_out_unescape_until, in, len, tt, u_rules) * so that if the output variable type changes, the parse rules are automatically changed. * @{ */ -size_t fr_sbuff_out_bool(bool *out, fr_sbuff_t *in); - -size_t fr_sbuff_out_int8(fr_sbuff_parse_error_t *err, int8_t *out, fr_sbuff_t *sbuff, bool no_trailing); -size_t fr_sbuff_out_int16(fr_sbuff_parse_error_t *err, int16_t *out, fr_sbuff_t *sbuff, bool no_trailing); -size_t fr_sbuff_out_int32(fr_sbuff_parse_error_t *err, int32_t *out, fr_sbuff_t *sbuff, bool no_trailing); -size_t fr_sbuff_out_int64(fr_sbuff_parse_error_t *err, int64_t *out, fr_sbuff_t *sbuff, bool no_trailing); -size_t fr_sbuff_out_uint8(fr_sbuff_parse_error_t *err, uint8_t *out, fr_sbuff_t *sbuff, bool no_trailing); -size_t fr_sbuff_out_uint16(fr_sbuff_parse_error_t *err, uint16_t *out, fr_sbuff_t *sbuff, bool no_trailing); -size_t fr_sbuff_out_uint32(fr_sbuff_parse_error_t *err, uint32_t *out, fr_sbuff_t *sbuff, bool no_trailing); -size_t fr_sbuff_out_uint64(fr_sbuff_parse_error_t *err, uint64_t *out, fr_sbuff_t *sbuff, bool no_trailing); - -size_t fr_sbuff_out_uint8_oct(fr_sbuff_parse_error_t *err, uint8_t *out, fr_sbuff_t *sbuff, bool no_trailing); -size_t fr_sbuff_out_uint16_oct(fr_sbuff_parse_error_t *err, uint16_t *out, fr_sbuff_t *sbuff, bool no_trailing); -size_t fr_sbuff_out_uint32_oct(fr_sbuff_parse_error_t *err, uint32_t *out, fr_sbuff_t *sbuff, bool no_trailing); -size_t fr_sbuff_out_uint64_oct(fr_sbuff_parse_error_t *err, uint64_t *out, fr_sbuff_t *sbuff, bool no_trailing); - -size_t fr_sbuff_out_uint8_hex(fr_sbuff_parse_error_t *err, uint8_t *out, fr_sbuff_t *sbuff, bool no_trailing); -size_t fr_sbuff_out_uint16_hex(fr_sbuff_parse_error_t *err, uint16_t *out, fr_sbuff_t *sbuff, bool no_trailing); -size_t fr_sbuff_out_uint32_hex(fr_sbuff_parse_error_t *err, uint32_t *out, fr_sbuff_t *sbuff, bool no_trailing); -size_t fr_sbuff_out_uint64_hex(fr_sbuff_parse_error_t *err, uint64_t *out, fr_sbuff_t *sbuff, bool no_trailing); - -size_t fr_sbuff_out_float32(fr_sbuff_parse_error_t *err, float *out, fr_sbuff_t *sbuff, bool no_trailing); -size_t fr_sbuff_out_float64(fr_sbuff_parse_error_t *err, double *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_bool(bool *out, fr_sbuff_t *in); + +fr_slen_t fr_sbuff_out_int8(fr_sbuff_parse_error_t *err, int8_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_int16(fr_sbuff_parse_error_t *err, int16_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_int32(fr_sbuff_parse_error_t *err, int32_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_int64(fr_sbuff_parse_error_t *err, int64_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_ssize(fr_sbuff_parse_error_t *err, ssize_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_uint8(fr_sbuff_parse_error_t *err, uint8_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_uint16(fr_sbuff_parse_error_t *err, uint16_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_uint32(fr_sbuff_parse_error_t *err, uint32_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_uint64(fr_sbuff_parse_error_t *err, uint64_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_size(fr_sbuff_parse_error_t *err, size_t *out, fr_sbuff_t *sbuff, bool no_trailing); + +fr_slen_t fr_sbuff_out_uint8_oct(fr_sbuff_parse_error_t *err, uint8_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_uint16_oct(fr_sbuff_parse_error_t *err, uint16_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_uint32_oct(fr_sbuff_parse_error_t *err, uint32_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_uint64_oct(fr_sbuff_parse_error_t *err, uint64_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_size_oct(fr_sbuff_parse_error_t *err, size_t *out, fr_sbuff_t *sbuff, bool no_trailing); + +fr_slen_t fr_sbuff_out_uint8_hex(fr_sbuff_parse_error_t *err, uint8_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_uint16_hex(fr_sbuff_parse_error_t *err, uint16_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_uint32_hex(fr_sbuff_parse_error_t *err, uint32_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_uint64_hex(fr_sbuff_parse_error_t *err, uint64_t *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_size_hex(fr_sbuff_parse_error_t *err, size_t *out, fr_sbuff_t *sbuff, bool no_trailing); + +fr_slen_t fr_sbuff_out_float32(fr_sbuff_parse_error_t *err, float *out, fr_sbuff_t *sbuff, bool no_trailing); +fr_slen_t fr_sbuff_out_float64(fr_sbuff_parse_error_t *err, double *out, fr_sbuff_t *sbuff, bool no_trailing); /** Parse a value based on the output type * @@ -1466,10 +1490,12 @@ size_t fr_sbuff_out_float64(fr_sbuff_parse_error_t *err, double *out, fr_sbuff_t int16_t * : fr_sbuff_out_int16(_err, (int16_t *)_out, _in, true), \ int32_t * : fr_sbuff_out_int32(_err, (int32_t *)_out, _in, true), \ int64_t * : fr_sbuff_out_int64(_err, (int64_t *)_out, _in, true), \ + ssize_t * : fr_sbuff_out_ssize(_err, (ssize_t *)_out, _in, true), \ uint8_t * : fr_sbuff_out_uint8(_err, (uint8_t *)_out, _in, true), \ uint16_t * : fr_sbuff_out_uint16(_err, (uint16_t *)_out, _in, true), \ uint32_t * : fr_sbuff_out_uint32(_err, (uint32_t *)_out, _in, true), \ uint64_t * : fr_sbuff_out_uint64(_err, (uint64_t *)_out, _in, true), \ + size_t * : fr_sbuff_out_size(_err, (size_t *)_out, _in, true), \ float * : fr_sbuff_out_float32(_err, (float *)_out, _in, true), \ double * : fr_sbuff_out_float64(_err, (double *)_out, _in, true) \ )