From: Nick Porter Date: Tue, 5 Aug 2025 11:29:39 +0000 (+0100) Subject: Better method of un-marshalling values from mRuby to FreeRADIUS X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=043e94da851691ea69c983226dc9aa0485b7f3f9;p=thirdparty%2Ffreeradius-server.git Better method of un-marshalling values from mRuby to FreeRADIUS --- diff --git a/src/modules/rlm_mruby/mruby.c b/src/modules/rlm_mruby/mruby.c index fb7bb0de19..441d2b1f93 100644 --- a/src/modules/rlm_mruby/mruby.c +++ b/src/modules/rlm_mruby/mruby.c @@ -321,91 +321,52 @@ static void mruby_pair_parent_build(mrb_state *mrb, mruby_pair_t *pair) */ static void mruby_ruby_to_pair_value(mrb_state *mrb, mrb_value *value, fr_pair_t *vp) { - switch (vp->vp_type) { - case FR_TYPE_STRING: - *value = mrb_obj_as_string(mrb, *value); - fr_pair_value_clear(vp); - fr_pair_value_bstrndup(vp, RSTRING_PTR(*value), RSTRING_LEN(*value), true); - break; + fr_value_box_t *vb = NULL; - case FR_TYPE_OCTETS: - *value = mrb_obj_as_string(mrb, *value); - fr_pair_value_clear(vp); - fr_pair_value_memdup(vp, (uint8_t *)RSTRING_PTR(*value), RSTRING_LEN(*value), true); + /* + * Convert the type provided by mRuby to the largest containing FreeRADIUS type + */ + switch (mrb_type(*value)) { + case MRB_TT_INTEGER: + MEM(vb = fr_value_box_alloc(NULL, FR_TYPE_INT64, NULL)); + vb->vb_int64 = mrb_integer(*value); break; -#define RUBYSETINT(_size) case FR_TYPE_INT ## _size: \ - if (mrb_type(*value) != MRB_TT_INTEGER) mrb_raise(mrb, E_ARGUMENT_ERROR, "Integer value required"); \ - vp->vp_int ## _size = mrb_integer(*value); \ - break; - RUBYSETINT(8) - RUBYSETINT(16) - RUBYSETINT(32) - RUBYSETINT(64) - -#define RUBYSETUINT(_size) case FR_TYPE_UINT ## _size: \ - if (mrb_type(*value) != MRB_TT_INTEGER) mrb_raise(mrb, E_ARGUMENT_ERROR, "Integer value required"); \ - vp->vp_uint ## _size = mrb_integer(*value); \ - break; - RUBYSETUINT(8) - RUBYSETUINT(16) - RUBYSETUINT(32) - RUBYSETUINT(64) - -#define RUBYSETFLOAT(_size) case FR_TYPE_FLOAT ## _size: \ - switch (mrb_type(*value)) { \ - case MRB_TT_FLOAT: \ - vp->vp_float ## _size = mrb_float(*value); \ - break; \ - case MRB_TT_INTEGER: \ - vp->vp_float ## _size = mrb_integer(*value); \ - break; \ - default: \ - mrb_raise(mrb, E_ARGUMENT_ERROR, "Float or integer value required"); \ - } \ - break; - RUBYSETFLOAT(32) - RUBYSETFLOAT(64) - - case FR_TYPE_SIZE: - if (mrb_type(*value) != MRB_TT_INTEGER) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "Integer value required"); - } - vp->vp_size = mrb_integer(*value); + case MRB_TT_FLOAT: + MEM(vb = fr_value_box_alloc(NULL, FR_TYPE_FLOAT64, NULL)); + vb->vb_float64 = mrb_float(*value); break; - case FR_TYPE_BOOL: - if (mrb_type(*value) == MRB_TT_TRUE) { - vp->vp_bool = true; - } else if (mrb_type(*value) == MRB_TT_FALSE) { - vp->vp_bool = false; - } else { - mrb_raise(mrb, E_ARGUMENT_ERROR, "Boolean value required"); - } + case MRB_TT_STRING: + MEM(vb = fr_value_box_alloc(NULL, FR_TYPE_STRING, NULL)); + fr_value_box_bstrndup_dbuff(vb, vb, NULL, + &FR_DBUFF_TMP((uint8_t *)RSTRING_PTR(*value), RSTRING_LEN(*value)), + RSTRING_LEN(*value), true); break; - case FR_TYPE_ETHERNET: - case FR_TYPE_IPV4_ADDR: - case FR_TYPE_IPV6_ADDR: - case FR_TYPE_IPV4_PREFIX: - case FR_TYPE_IPV6_PREFIX: - case FR_TYPE_COMBO_IP_ADDR: - case FR_TYPE_COMBO_IP_PREFIX: - case FR_TYPE_IFID: - case FR_TYPE_TIME_DELTA: - case FR_TYPE_DATE: - case FR_TYPE_ATTR: - - *value = mrb_obj_as_string(mrb, *value); - if (fr_pair_value_from_str(vp, RSTRING_PTR(*value), RSTRING_LEN(*value), NULL, false) < 0) { - mrb_raise(mrb, E_RUNTIME_ERROR, "Failed populating pair"); - } + case MRB_TT_TRUE: + MEM(vb = fr_value_box_alloc(NULL, FR_TYPE_BOOL, NULL)); + vb->vb_bool = true; break; - case FR_TYPE_NON_LEAF: - fr_assert(0); + case MRB_TT_FALSE: + MEM(vb = fr_value_box_alloc(NULL, FR_TYPE_BOOL, NULL)); + vb->vb_bool = false; break; + + default: + mrb_raise(mrb, E_ARGUMENT_ERROR, "Unsupported value type"); + } + + /* + * Cast the converted value to the required type for the pair + */ + fr_pair_value_clear(vp); + if (fr_value_box_cast(vp, &vp->data, vp->vp_type, vp->da, vb) < 0) { + talloc_free(vb); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "Failed casting ruby value to %s", fr_type_to_str(vp->vp_type)); } + talloc_free(vb); } /** Set a value pair from mruby