From 29d012c9641fa53464a03cc682b6a0f5bf7888df Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Tue, 29 Dec 2020 16:35:25 +0900 Subject: [ruby/bigdecimal] Alloc wrapper object before VpAlloc Calling TypedData_Wrap_Struct after VpAlloc may cause memory leak. This commit reverts d11b78f9c420f39ee800b9feed4839cd28f4ff5c. https://github.com/ruby/bigdecimal/commit/2c5a288caf --- ext/bigdecimal/bigdecimal.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'ext/bigdecimal') diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index f659359c60..89653f4904 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -2792,12 +2792,14 @@ rb_str_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) digs = 0; const char *c_str = StringValueCStr(val); + VALUE obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, 0); Real *vp = VpAlloc(digs, c_str, 1, raise_exception); if (!vp) return Qnil; - vp->obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, vp); - RB_OBJ_FREEZE(vp->obj); - return check_exception(vp->obj); + RTYPEDDATA_DATA(obj) = vp; + vp->obj = obj; + RB_OBJ_FREEZE(obj); + return VpCheckGetValue(vp); } static VALUE @@ -2822,10 +2824,13 @@ rb_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) Real *vp; TypedData_Get_Struct(val, Real, &BigDecimal_data_type, vp); + + VALUE copy = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, 0); vp = VpCopy(NULL, vp); - vp->obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, vp); + RTYPEDDATA_DATA(copy) = vp; + vp->obj = copy; RB_OBJ_FREEZE(vp->obj); - return check_exception(vp->obj); + return VpCheckGetValue(vp); } else if (RB_INTEGER_TYPE_P(val)) { return rb_inum_convert_to_BigDecimal(val, digs, raise_exception); @@ -2929,14 +2934,16 @@ static VALUE BigDecimal_s_interpret_loosely(VALUE klass, VALUE str) { ENTER(1); - char const *c_str; - Real *pv; - c_str = StringValueCStr(str); + char const *c_str = StringValueCStr(str); + VALUE obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, 0); + + Real *pv; GUARD_OBJ(pv, VpAlloc(0, c_str, 0, 1)); - pv->obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, pv); + RTYPEDDATA_DATA(obj) = pv; + pv->obj = obj; RB_OBJ_FREEZE(pv->obj); - return pv->obj; + return obj; } /* call-seq: -- cgit v1.2.3