29 #include <freeradius-devel/util/debug.h>
30 #include <freeradius-devel/util/base16.h>
31 #include <freeradius-devel/util/sbuff.h>
32 #include <freeradius-devel/util/types.h>
33 #include <freeradius-devel/util/value.h>
47 .value = { .value_is_always_array =
true },
71 static inline CC_HINT(always_inline)
76 ret = json_object_put(obj);
79 fr_assert_fail(
"json_object_put did not free object (returned %u), likely leaking memory", ret);
99 switch (json_object_get_type(
object)) {
100 case json_type_string:
106 value = json_object_get_string(
object);
107 len = json_object_get_string_len(
object);
109 if (!enumv)
goto no_enumv;
130 case json_type_double:
136 #ifdef HAVE_JSON_OBJECT_GET_INT64
142 #ifndef HAVE_JSON_OBJECT_GET_INT64
143 num = json_object_get_int(
object);
145 num = json_object_get_int64(
object);
146 if (num < INT32_MIN) {
148 }
else if (num > UINT32_MAX) {
152 if (num < INT16_MIN) {
154 }
else if (num < INT8_MIN) {
156 }
else if (num < 0) {
158 }
else if (num > UINT16_MAX) {
168 case json_type_boolean:
170 fr_value_box(
out, ((
bool)(json_object_get_boolean(
object) > 0)), tainted);
174 case json_type_array:
175 case json_type_object:
177 char const *
value = json_object_to_json_string(
object);
184 out->tainted = tainted;
204 if (enumv)
return json_object_new_string(enumv->
name);
207 switch (
data->type) {
220 return json_object_new_string_len(
data->vb_strvalue,
data->vb_length);
223 return json_object_new_string_len((
char const *)
data->vb_octets,
data->vb_length);
226 return json_object_new_boolean(
data->vb_uint8);
229 return json_object_new_int(
data->vb_uint8);
232 return json_object_new_int(
data->vb_uint16);
234 #ifdef HAVE_JSON_OBJECT_GET_INT64
236 return json_object_new_int64((int64_t)
data->vb_uint64);
239 if (
data->vb_uint64 > INT64_MAX)
goto do_string;
240 return json_object_new_int64(
data->vb_uint64);
243 if (
data->vb_uint32 > INT32_MAX)
goto do_string;
244 return json_object_new_int(
data->vb_uint32);
248 return json_object_new_int(
data->vb_int8);
251 return json_object_new_int(
data->vb_int16);
254 return json_object_new_int(
data->vb_int32);
256 #ifdef HAVE_JSON_OBJECT_GET_INT64
258 return json_object_new_int64(
data->vb_int64);
261 return json_object_new_int64(
data->vb_size);
300 char const *last_app, *p, *end;
304 last_app = p = vb->vb_strvalue;
305 end = p + vb->vb_length;
400 struct json_object *obj;
403 obj = json_object_new_double((
double)vb->vb_float32);
404 if (
unlikely(obj == NULL))
return -1;
412 struct json_object *obj;
415 obj = json_object_new_double((
double)vb->vb_float64);
416 if (
unlikely(obj == NULL))
return -1;
438 if (slen < 0)
return slen;
461 #ifdef HAVE_JSON_C_VERSION
462 INFO(
"libfreeradius-json: json-c version: %s", json_c_version());
464 INFO(
"libfreeradius-json: json-c version: Unknown (less than 0.10) - Please upgrade");
489 struct json_object *obj;
540 if (
format->attr.prefix) {
565 switch (
format->output_mode) {
572 if (
format->attr.prefix) {
573 if (verbose)
WARN(
"attribute name prefix not valid in output_mode 'array_of_values' and will be ignored");
576 if (
format->value.value_is_always_array) {
577 if (verbose)
WARN(
"'value_is_always_array' not valid in output_mode 'array_of_values' and will be ignored");
582 if (
format->value.value_is_always_array) {
583 if (verbose)
WARN(
"'value_is_always_array' not valid in output_mode 'array_of_names' and will be ignored");
586 if (
format->value.enum_as_int) {
587 if (verbose)
WARN(
"'enum_as_int' not valid in output_mode 'array_of_names' and will be ignored");
590 if (
format->value.always_string) {
591 if (verbose)
WARN(
"'always_string' not valid in output_mode 'array_of_names' and will be ignored");
596 ERROR(
"JSON format output mode is invalid");
605 #define INVALID_TYPE \
608 fr_strerror_printf("Invalid type %s for attribute %s", fr_type_to_str(vp->vp_type), vp->da->name); \
648 struct json_object *obj;
655 MEM(obj = json_object_new_object());
661 struct json_object *vp_object, *values, *
value, *type_name;
663 if (
vp->vp_raw)
continue;
673 switch (
vp->vp_type) {
721 if (!json_object_object_get_ex(obj,
fr_sbuff_start(&attr_name), &vp_object)) {
725 MEM(vp_object = json_object_new_object());
726 json_object_object_add(obj,
fr_sbuff_start(&attr_name), vp_object);
732 json_object_object_add_ex(vp_object,
"type", type_name, JSON_C_OBJECT_KEY_IS_CONSTANT);
737 if (
format->value.value_is_always_array) {
738 MEM(values = json_object_new_array());
739 json_object_object_add_ex(vp_object,
"value", values, JSON_C_OBJECT_KEY_IS_CONSTANT);
740 json_object_array_add(values,
value);
747 json_object_object_add_ex(vp_object,
"value",
value, JSON_C_OBJECT_KEY_IS_CONSTANT);
755 if (!
fr_cond_assert(json_object_object_get_ex(vp_object,
"value", &values))) {
764 if (!
format->value.value_is_always_array) {
766 struct json_object *convert_value = values;
769 type = json_object_get_type(values);
772 if (
type != json_type_array) {
773 MEM(values = json_object_new_array());
774 json_object_array_add(values, json_object_get(convert_value));
775 json_object_object_del(vp_object,
"value");
776 json_object_object_add_ex(vp_object,
"value", values,
777 JSON_C_OBJECT_KEY_IS_CONSTANT);
780 json_object_array_add(values,
value);
815 struct json_object *obj;
823 MEM(obj = json_object_new_object());
829 struct json_object *vp_object, *
value;
830 struct json_object *values = NULL;
831 bool add_single =
false;
833 if (
vp->vp_raw)
continue;
843 switch (
vp->vp_type) {
880 if (!json_object_object_get_ex(obj,
fr_sbuff_start(&attr_name), &vp_object)) {
881 if (
format->value.value_is_always_array) {
886 MEM(values = json_object_new_array());
898 type = json_object_get_type(vp_object);
900 if (
type == json_type_array) {
907 MEM(values = json_object_new_array());
908 json_object_array_add(values, json_object_get(vp_object));
928 json_object_array_add(values,
value);
954 struct json_object *obj;
955 struct json_object *seen_attributes = NULL;
962 MEM(obj = json_object_new_array());
968 if (
format->value.value_is_always_array) {
969 seen_attributes = json_object_new_object();
976 struct json_object *
name, *
value, *type_name;
977 struct json_object *values = NULL;
978 struct json_object *attrobj = NULL;
979 bool already_seen =
false;
981 if (
vp->vp_raw)
continue;
991 switch (
vp->vp_type) {
1008 if (
format->value.value_is_always_array) {
1013 already_seen = json_object_object_get_ex(seen_attributes,
fr_sbuff_start(&attr_name), &values);
1021 if (!
format->value.value_is_always_array || !already_seen) {
1025 MEM(attrobj = json_object_new_object());
1026 json_object_array_add(obj, attrobj);
1032 json_object_object_add_ex(attrobj,
"name",
name, JSON_C_OBJECT_KEY_IS_CONSTANT);
1035 json_object_object_add_ex(attrobj,
"type", type_name, JSON_C_OBJECT_KEY_IS_CONSTANT);
1038 if (
format->value.value_is_always_array) {
1043 if (!already_seen) {
1044 MEM(values = json_object_new_array());
1048 json_object_object_add_ex(attrobj,
"value", values, JSON_C_OBJECT_KEY_IS_CONSTANT);
1053 json_object_object_add(seen_attributes,
fr_sbuff_start(&attr_name), json_object_get(values));
1059 json_object_array_add(values,
value);
1064 json_object_object_add_ex(attrobj,
"value",
value, JSON_C_OBJECT_KEY_IS_CONSTANT);
1072 if (
format->value.value_is_always_array) {
1099 struct json_object *obj;
1105 MEM(obj = json_object_new_array());
1114 struct json_object *
value;
1116 if (
vp->vp_raw)
continue;
1118 switch (
vp->vp_type) {
1135 json_object_array_add(obj,
value);
1161 struct json_object *obj;
1168 MEM(obj = json_object_new_array());
1176 struct json_object *
value;
1179 if (
vp->vp_raw)
continue;
1187 switch (
vp->vp_type) {
1192 json_object_array_add(obj,
value);
1200 json_object_array_add(obj,
value);
1242 struct json_object *obj = NULL;
1248 switch (
format->output_mode) {
1273 MEM(p = json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN));
static int const char char buffer[256]
#define fr_base16_encode(_out, _in)
#define L(_str)
Helper for initialising arrays of string literals.
#define CONF_PARSER_TERMINATOR
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
Defines a CONF_PAIR to C data type mapping.
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#define fr_assert_fail(_msg,...)
Calls panic_action ifndef NDEBUG, else logs error.
fr_dict_enum_value_t * fr_dict_enum_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value)
Lookup the structure representing an enum value in a fr_dict_attr_t.
fr_value_box_t const * value
Enum value (what name maps to).
fr_dict_enum_value_t * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
ssize_t fr_dict_valid_name(char const *name, ssize_t len)
char const * name
Enum name.
#define FR_DICT_ATTR_MAX_NAME_LEN
Maximum length of a attribute name.
Value of an enumerated attribute.
@ JSON_MODE_ARRAY_OF_NAMES
@ JSON_MODE_OBJECT_SIMPLE
@ JSON_MODE_ARRAY_OF_VALUES
fr_json_format_attr_t attr
Formatting options for attribute names.
char const * prefix
Prefix to add to all attribute names.
json_object * json_object_from_value_box(fr_value_box_t const *data)
Convert boxed value_box to a JSON object.
static fr_json_format_t const default_json_format
static void json_object_put_assert(json_object *obj)
size_t fr_json_format_table_len
static conf_parser_t const json_format_value_config[]
static json_object * json_object_afrom_pair_list(TALLOC_CTX *ctx, fr_pair_list_t *vps, fr_json_format_t const *format)
Returns a JSON object representation of a list of value pairs.
static json_object * json_smplobj_afrom_pair_list(TALLOC_CTX *ctx, fr_pair_list_t *vps, fr_json_format_t const *format)
Returns a JSON object representation of a list of value pairs.
static conf_parser_t const json_format_attr_config[]
fr_slen_t fr_json_str_from_value(fr_sbuff_t *out, fr_value_box_t *vb, bool include_quotes)
Print a value box as its equivalent JSON format without going via a struct json_object (in most cases...
static int json_afrom_value_box(TALLOC_CTX *ctx, json_object **out, fr_pair_t *vp, fr_json_format_t const *format)
Convert fr_pair_t into a JSON object.
conf_parser_t const fr_json_format_config[]
void fr_json_version_print(void)
Print JSON-C version.
fr_table_num_sorted_t const fr_json_format_table[]
static struct json_object * json_value_array_afrom_pair_list(TALLOC_CTX *ctx, fr_pair_list_t *vps, fr_json_format_t const *format)
Returns a JSON array of a list of value pairs.
int fr_json_object_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *out, json_object *object, fr_dict_attr_t const *enumv, bool tainted)
Convert json object to fr_value_box_t.
static struct json_object * json_array_afrom_pair_list(TALLOC_CTX *ctx, fr_pair_list_t *vps, fr_json_format_t const *format)
Returns a JSON array representation of a list of value pairs.
bool fr_json_format_verify(fr_json_format_t const *format, bool verbose)
Verify that the options in fr_json_format_t are valid.
static ssize_t attr_name_with_prefix(fr_sbuff_t *out, fr_dict_attr_t const *da, fr_json_format_t const *format)
Get attribute name with optional prefix.
static struct json_object * json_attr_array_afrom_pair_list(TALLOC_CTX *ctx, fr_pair_list_t *vps, fr_json_format_t const *format)
Returns a JSON array of a list of value pairs.
char * fr_json_afrom_pair_list(TALLOC_CTX *ctx, fr_pair_list_t *vps, fr_json_format_t const *format)
Returns a JSON string of a list of value pairs.
@ 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_VALUE_BOX
A boxed value.
@ 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_FLOAT64
Double precision floating point.
int fr_pair_value_enum_box(fr_value_box_t const **out, fr_pair_t *vp)
Get value box of a VP, optionally prefer enum value.
ssize_t fr_sbuff_in_strcpy(fr_sbuff_t *sbuff, char const *str)
Copy bytes into the sbuff up to the first \0.
#define fr_sbuff_start(_sbuff_or_marker)
#define FR_SBUFF_IN_CHAR_RETURN(_sbuff,...)
#define fr_sbuff_set(_dst, _src)
#define FR_SBUFF_IN(_start, _len_or_end)
#define FR_SBUFF_IN_STRCPY_LITERAL_RETURN(_sbuff, _str)
#define FR_SBUFF_IN_SPRINTF_RETURN(...)
#define FR_SBUFF(_sbuff_or_marker)
#define FR_SBUFF_IN_BSTRNCPY_RETURN(...)
#define fr_sbuff_init_in(_out, _start, _len_or_end)
#define fr_sbuff_used(_sbuff_or_marker)
#define FR_SBUFF_IN_STRCPY_RETURN(...)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
fr_aka_sim_id_type_t type
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
An element in a lexicographically sorted array of name to num mappings.
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Master include file to access all functions and structures in the library.
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
#define FR_TYPE_STRUCTURAL
ssize_t fr_value_box_print(fr_sbuff_t *out, fr_value_box_t const *data, fr_sbuff_escape_rules_t const *e_rules)
Print one boxed value to a string.
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.
FR_SBUFF_SET_RETURN(sbuff, &our_sbuff)
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.
#define FR_VALUE_BOX_INITIALISER_NULL(_vb)
A static initialiser for stack/globally allocated boxes.
#define fr_value_box(_box, _var, _tainted)
Automagically fill in a box, determining the value type from the type of the C variable.
int format(printf, 5, 0))
static size_t char ** out