summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenta Murata <mrkn@mrkn.jp>2020-12-29 16:35:25 +0900
committerKenta Murata <mrkn@mrkn.jp>2020-12-29 17:46:36 +0900
commit29d012c9641fa53464a03cc682b6a0f5bf7888df (patch)
treea201c4370bb4c680228e36d09d1a4bebf8bacb14
parent13b520d578d7e4cbfb904199574fa081458a64f8 (diff)
[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
-rw-r--r--ext/bigdecimal/bigdecimal.c27
1 files changed, 17 insertions, 10 deletions
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: