]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Split the cast operation out of fr_json_object_to_value_box
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 23 May 2018 13:09:30 +0000 (19:09 +0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 23 May 2018 17:57:24 +0000 (23:57 +0600)
src/modules/rlm_json/jpath.c
src/modules/rlm_json/json.c
src/modules/rlm_json/json.h

index d6dbb100731ad15318b3bf5e1756b30adb474c36..9e7c2f8e3da7cced73c442f6268881347725b204 100644 (file)
@@ -338,7 +338,7 @@ static int jpath_evaluate(TALLOC_CTX *ctx, fr_value_box_t ***tail,
        case JPATH_SELECTOR_ROOT:
        case JPATH_SELECTOR_CURRENT:
                rad_assert(0);
-               return -1;      /* Not yet implemented */
+               return -1;              /* Not yet implemented */
        }
 
        /*
@@ -346,11 +346,17 @@ static int jpath_evaluate(TALLOC_CTX *ctx, fr_value_box_t ***tail,
         *      we now attempt conversion of the leaf to
         *      the specified value.
         */
-       value = talloc_zero(ctx, fr_value_box_t);
-       if (fr_json_object_to_value_box(value, value, object, dst_type, dst_enumv) < 0) {
+       value = fr_value_box_alloc_null(ctx);
+       if (fr_json_object_to_value_box(value, value, object, dst_enumv, true) < 0) {
                talloc_free(value);
                return -1;
        }
+
+       if (fr_value_box_cast_in_place(value, value, dst_type, dst_enumv) < 0) {
+               talloc_free(value);
+               return -1;
+       }
+
        **tail = value;
        *tail = &(**tail)->next;
        return 1;
index 24cbd4cb1717fa401f9b8866b1879ece1dfbb237..7a2d34f1ce40bb001c1e7320cf183a2cab0b8d2b 100644 (file)
 /** Convert json object to fr_value_box_t
  *
  * @param[in] ctx      to allocate any value buffers in (should usually be the same as out).
- * @param[in] out      Where to write value_box.
+ * @param[in] out      Where to write value.  Must be initialised.
  * @param[in] object   to convert.
- * @param[in] dst_type FreeRADIUS type to convert to.
- * @param[in] dst_enumv        Enumeration values to allow string to integer conversions.
+ * @param[in] enumv    Any string values are assumed to be in PRESENTATION format, meaning
+ *                     that if an enumv is specified, they'll be checked against the list
+ *                     of aliases for that enumeration, and possibly converted into one of
+ *                     the enumeration values (which may not be a string).
+ * @param[in] tainted  Whether the data source is untrusted.
  * @return
  *     - 0 on success.
  *     - -1 on failure.
  */
 int fr_json_object_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *out, json_object *object,
-                               fr_type_t dst_type, fr_dict_attr_t const *dst_enumv)
+                               fr_dict_attr_t const *enumv, bool tainted)
 {
-       fr_value_box_t in;
-
-       memset(&in, 0, sizeof(in));
-
        switch (fr_json_object_get_type(object)) {
        case json_type_string:
-               in.type = FR_TYPE_STRING;
-               in.vb_strvalue = json_object_get_string(object);
-               in.datum.length = json_object_get_string_len(object);
+       {
+               char const      *value;
+               size_t          len;
+               fr_dict_enum_t  *found;
+
+               value = json_object_get_string(object);
+               len = json_object_get_string_len(object);
+
+               if (!enumv) goto no_enumv;
+
+               if (fr_dict_valid_name(value, len) < 0) goto no_enumv;
+
+               /*
+                *      If an alias exists, use that value instead
+                */
+               found = fr_dict_enum_by_alias(enumv, value, len);
+               if (found) {
+                       if (fr_value_box_copy(ctx, out, found->value) < 0) return -1;
+                       return 0;
+               }
+
+       no_enumv:
+               /*
+                *      Just copy the string to the box.
+                */
+               fr_value_box_bstrndup(ctx, out, NULL, value, len, tainted);
+       }
                break;
 
        case json_type_double:
-               in.type = FR_TYPE_FLOAT64;
-               in.vb_float64 = json_object_get_double(object);
+               out->type = FR_TYPE_FLOAT64;
+               out->vb_float64 = json_object_get_double(object);
                break;
 
        case json_type_int:
@@ -78,50 +101,52 @@ int fr_json_object_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *out, json_objec
 #else
                num = json_object_get_int64(object);
                if (num < INT32_MIN) {                  /* 64bit signed*/
-                       in.type = FR_TYPE_INT64;
-                       in.vb_int64 = (int64_t) num;
+                       out->type = FR_TYPE_INT64;
+                       out->vb_int64 = (int64_t) num;
                } else if (num > UINT32_MAX) {          /* 64bit unsigned */
-                       in.type = FR_TYPE_UINT64;
-                       in.vb_uint64 = (uint64_t) num;
+                       out->type = FR_TYPE_UINT64;
+                       out->vb_uint64 = (uint64_t) num;
                } else
 #endif
                if (num < INT16_MIN) {                  /* 32bit signed */
-                       in.type = FR_TYPE_INT32;
-                       in.vb_int32 = (int32_t)num;
+                       out->type = FR_TYPE_INT32;
+                       out->vb_int32 = (int32_t)num;
                } else if (num < INT8_MIN) {            /* 16bit signed */
-                       in.type = FR_TYPE_INT16;
-                       in.vb_int16 = (int16_t)num;
+                       out->type = FR_TYPE_INT16;
+                       out->vb_int16 = (int16_t)num;
                } else if (num < 0) {                   /* 8bit signed */
-                       in.type = FR_TYPE_INT8;
-                       in.vb_int8 = (int8_t)num;
+                       out->type = FR_TYPE_INT8;
+                       out->vb_int8 = (int8_t)num;
                } else if (num > UINT16_MAX) {          /* 32bit unsigned */
-                       in.type = FR_TYPE_UINT32;
-                       in.vb_uint32 = (uint32_t) num;
+                       out->type = FR_TYPE_UINT32;
+                       out->vb_uint32 = (uint32_t) num;
                } else if (num > UINT8_MAX) {           /* 16bit unsigned */
-                       in.type = FR_TYPE_UINT16;
-                       in.vb_uint16 = (uint16_t) num;
+                       out->type = FR_TYPE_UINT16;
+                       out->vb_uint16 = (uint16_t) num;
                } else {                                /* 8bit unsigned */
-                       in.type = FR_TYPE_UINT8;
-                       in.vb_uint8 = (uint8_t) num;
+                       out->type = FR_TYPE_UINT8;
+                       out->vb_uint8 = (uint8_t) num;
                }
        }
                break;
 
        case json_type_boolean:
-               in.type = FR_TYPE_BOOL;
-               in.datum.boolean = json_object_get_boolean(object);
+               out->type = FR_TYPE_BOOL;
+               out->datum.boolean = json_object_get_boolean(object);
                break;
 
        case json_type_null:
        case json_type_array:
        case json_type_object:
-               in.type = FR_TYPE_STRING;
-               in.vb_strvalue = json_object_to_json_string(object);
-               in.datum.length = strlen(in.vb_strvalue);
+       {
+               char const *value = json_object_to_json_string(object);
+
+               fr_value_box_bstrndup(ctx, out, NULL, value, strlen(value), tainted);
+       }
                break;
        }
 
-       if (fr_value_box_cast(ctx, out, dst_type, dst_enumv, &in) < 0) return -1;
+       out->tainted = tainted;
 
        return 0;
 }
@@ -133,6 +158,18 @@ int fr_json_object_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *out, json_objec
  */
 json_object *json_object_from_value_box(TALLOC_CTX *ctx, fr_value_box_t const *data)
 {
+       /*
+        *      We're converting to PRESENTATION format
+        *      so any attributes with enumeration values
+        *      should be converted to string types.
+        */
+       if (data->enumv) {
+               fr_dict_enum_t *enumv;
+
+               enumv = fr_dict_enum_by_value(data->enumv, data);
+               if (enumv) return json_object_new_string(enumv->alias);
+       }
+
        switch (data->type) {
        default:
        do_string:
index 8309ad8a20f37bacc61509c82068668d36ced802..80c23e12bf0c592733226a3e6d392908d2466de7 100644 (file)
@@ -58,7 +58,7 @@ ssize_t               fr_jpath_parse(TALLOC_CTX *ctx, fr_jpath_node_t **head, char const *in,
 
 /* json.c */
 int            fr_json_object_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *out, json_object *object,
-                                           fr_type_t dst_type, fr_dict_attr_t const *dst_enumv);
+                                           fr_dict_attr_t const *enumv, bool tainted);
 
 json_object    *json_object_from_value_box(TALLOC_CTX *ctx, fr_value_box_t const *data);