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 },
 
 
   71static 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;
 
  439                if (slen < 0) 
return slen;
 
 
  460#ifdef HAVE_JSON_C_VERSION 
  461        INFO(
"libfreeradius-json: json-c version: %s", json_c_version());
 
  463        INFO(
"libfreeradius-json: json-c version: Unknown (less than 0.10) - Please upgrade");
 
 
  488        struct json_object      *obj;
 
 
  539        if (
format->attr.prefix) {
 
 
  564        switch (
format->output_mode) {
 
  571                if (
format->attr.prefix) {
 
  572                        if (verbose) 
WARN(
"attribute name prefix not valid in output_mode 'array_of_values' and will be ignored");
 
  575                if (
format->value.value_is_always_array) {
 
  576                        if (verbose) 
WARN(
"'value_is_always_array' not valid in output_mode 'array_of_values' and will be ignored");
 
  581                if (
format->value.value_is_always_array) {
 
  582                        if (verbose) 
WARN(
"'value_is_always_array' not valid in output_mode 'array_of_names' and will be ignored");
 
  585                if (
format->value.enum_as_int) {
 
  586                        if (verbose) 
WARN(
"'enum_as_int' not valid in output_mode 'array_of_names' and will be ignored");
 
  589                if (
format->value.always_string) {
 
  590                        if (verbose) 
WARN(
"'always_string' not valid in output_mode 'array_of_names' and will be ignored");
 
  595                ERROR(
"JSON format output mode is invalid");
 
 
  604#define INVALID_TYPE \ 
  607        fr_strerror_printf("Invalid type %s for attribute %s", fr_type_to_str(vp->vp_type), vp->da->name); \ 
 
  647        struct json_object      *obj;
 
  654        MEM(obj = json_object_new_object());
 
  660                struct json_object      *vp_object, *values, *
value, *type_name;
 
  662                if (
vp->vp_raw) 
continue;
 
  672                switch (
vp->vp_type) {
 
  720                if (!json_object_object_get_ex(obj, 
fr_sbuff_start(&attr_name), &vp_object)) {
 
  724                        MEM(vp_object = json_object_new_object());
 
  725                        json_object_object_add(obj, 
fr_sbuff_start(&attr_name), vp_object);
 
  731                        json_object_object_add_ex(vp_object, 
"type", type_name, JSON_C_OBJECT_KEY_IS_CONSTANT);
 
  736                        if (
format->value.value_is_always_array) {
 
  737                                MEM(values = json_object_new_array());
 
  738                                json_object_object_add_ex(vp_object, 
"value", values, JSON_C_OBJECT_KEY_IS_CONSTANT);
 
  739                                json_object_array_add(values, 
value);
 
  746                        json_object_object_add_ex(vp_object, 
"value", 
value, JSON_C_OBJECT_KEY_IS_CONSTANT);
 
  754                if (!
fr_cond_assert(json_object_object_get_ex(vp_object, 
"value", &values))) {
 
  763                if (!
format->value.value_is_always_array) {
 
  765                        struct json_object      *convert_value = values;
 
  768                        type = json_object_get_type(values);
 
  771                        if (
type != json_type_array) {
 
  772                                MEM(values = json_object_new_array());
 
  773                                json_object_array_add(values, json_object_get(convert_value));
 
  774                                json_object_object_del(vp_object, 
"value");
 
  775                                json_object_object_add_ex(vp_object, 
"value", values,
 
  776                                                                JSON_C_OBJECT_KEY_IS_CONSTANT);
 
  779                json_object_array_add(values, 
value);
 
 
  814        struct json_object      *obj;
 
  822        MEM(obj = json_object_new_object());
 
  828                struct json_object      *vp_object, *
value;
 
  829                struct json_object      *values = NULL;
 
  830                bool                    add_single = 
false;
 
  832                if (
vp->vp_raw) 
continue;
 
  842                switch (
vp->vp_type) {
 
  879                if (!json_object_object_get_ex(obj, 
fr_sbuff_start(&attr_name), &vp_object)) {
 
  880                        if (
format->value.value_is_always_array) {
 
  885                                MEM(values = json_object_new_array());
 
  897                        type = json_object_get_type(vp_object);
 
  899                        if (
type == json_type_array) {
 
  906                                MEM(values = json_object_new_array());
 
  907                                json_object_array_add(values, json_object_get(vp_object));
 
  927                        json_object_array_add(values, 
value);
 
 
  953        struct json_object      *obj;
 
  954        struct json_object      *seen_attributes = NULL;
 
  961        MEM(obj = json_object_new_array());
 
  967        if (
format->value.value_is_always_array) {
 
  968                seen_attributes = json_object_new_object();
 
  975                struct json_object      *
name, *
value, *type_name;
 
  976                struct json_object      *values = NULL;
 
  977                struct json_object      *attrobj = NULL;
 
  978                bool                    already_seen = 
false;
 
  980                if (
vp->vp_raw) 
continue;
 
  990                switch (
vp->vp_type) {
 
 1007                if (
format->value.value_is_always_array) {
 
 1012                        already_seen = json_object_object_get_ex(seen_attributes, 
fr_sbuff_start(&attr_name), &values);
 
 1020                if (!
format->value.value_is_always_array || !already_seen) {
 
 1024                        MEM(attrobj = json_object_new_object());
 
 1025                        json_object_array_add(obj, attrobj);
 
 1031                        json_object_object_add_ex(attrobj, 
"name", 
name, JSON_C_OBJECT_KEY_IS_CONSTANT);
 
 1034                        json_object_object_add_ex(attrobj, 
"type", type_name, JSON_C_OBJECT_KEY_IS_CONSTANT);
 
 1037                if (
format->value.value_is_always_array) {
 
 1042                        if (!already_seen) {
 
 1043                                MEM(values = json_object_new_array());
 
 1047                                json_object_object_add_ex(attrobj, 
"value", values, JSON_C_OBJECT_KEY_IS_CONSTANT);
 
 1052                                json_object_object_add(seen_attributes, 
fr_sbuff_start(&attr_name), json_object_get(values));
 
 1058                        json_object_array_add(values, 
value);
 
 1063                        json_object_object_add_ex(attrobj, 
"value", 
value, JSON_C_OBJECT_KEY_IS_CONSTANT);
 
 1071        if (
format->value.value_is_always_array) {
 
 
 1098        struct json_object      *obj;
 
 1104        MEM(obj = json_object_new_array());
 
 1113                struct json_object      *
value;
 
 1115                if (
vp->vp_raw) 
continue;
 
 1117                switch (
vp->vp_type) {
 
 1134                json_object_array_add(obj, 
value);
 
 
 1160        struct json_object      *obj;
 
 1167        MEM(obj = json_object_new_array());
 
 1175                struct json_object      *
value;
 
 1178                if (
vp->vp_raw) 
continue;
 
 1186                switch (
vp->vp_type) {
 
 1191                        json_object_array_add(obj, 
value);
 
 1199                json_object_array_add(obj, 
value);
 
 
 1241        struct json_object      *obj = NULL;
 
 1247        switch (
format->output_mode) {
 
 1272        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_value_box_t const  * value
Enum value (what name maps to).
fr_dict_enum_value_t const * 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.
ssize_t fr_dict_valid_name(char const *name, ssize_t len)
fr_dict_enum_value_t const * fr_dict_enum_by_name(fr_dict_attr_t const *da, 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.
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 fr_json_format_t const default_json_format
static void json_object_put_assert(json_object *obj)
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.
size_t fr_json_format_table_len
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.
static conf_parser_t const json_format_value_config[]
json_object * json_object_from_value_box(fr_value_box_t const *data)
Convert boxed value_box to a JSON object.
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_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.
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 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.
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.
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.
@ 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_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_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_STRCPY_LITERAL_RETURN(_sbuff, _str)
#define FR_SBUFF_SET_RETURN(_dst, _src)
#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_OUT(_start, _len_or_end)
#define fr_sbuff_used(_sbuff_or_marker)
#define FR_SBUFF_IN_STRCPY_RETURN(...)
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_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
@ FR_TYPE_ATTR
A contains an attribute reference.
#define FR_TYPE_STRUCTURAL
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
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.
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