aboutsummaryrefslogtreecommitdiffstats
path: root/internal.h
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2019-10-05 02:08:07 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2019-10-05 03:02:09 +0900
commitcbbe198c89fa25a80ec0a5f0592ea00132eacd01 (patch)
tree3913c6ed543ca51f23c1f38a810da647f8c5563d /internal.h
parentc8a18e25c1cc9a44231b97e12f30a98cf9d979bb (diff)
downloadruby-cbbe198c89fa25a80ec0a5f0592ea00132eacd01.tar.gz
Fix potential memory leaks by `rb_imemo_tmpbuf_auto_free_pointer`
This function has been used wrongly always at first, "allocate a buffer then wrap it with tmpbuf". This order can cause a memory leak, as tmpbuf creation also can raise a NoMemoryError exception. The right order is "create a tmpbuf then allocate&wrap a buffer". So the argument of this function is rather harmful than just useless. TODO: * Rename this function to more proper name, as it is not used "temporary" (function local) purpose. * Allocate and wrap at once safely, like `ALLOCV`.
Diffstat (limited to 'internal.h')
-rw-r--r--internal.h12
1 files changed, 10 insertions, 2 deletions
diff --git a/internal.h b/internal.h
index 7d24e33bd1..e653f30b44 100644
--- a/internal.h
+++ b/internal.h
@@ -1134,6 +1134,8 @@ imemo_type_p(VALUE imemo, enum imemo_type imemo_type)
}
}
+VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0);
+
/* FL_USER0 to FL_USER3 is for type */
#define IMEMO_FL_USHIFT (FL_USHIFT + 4)
#define IMEMO_FL_USER0 FL_USER4
@@ -1203,13 +1205,19 @@ typedef struct rb_imemo_tmpbuf_struct {
size_t cnt; /* buffer size in VALUE */
} rb_imemo_tmpbuf_t;
-VALUE rb_imemo_tmpbuf_auto_free_pointer(void *buf);
+#define rb_imemo_tmpbuf_auto_free_pointer() rb_imemo_new(imemo_tmpbuf, 0, 0, 0, 0)
VALUE rb_imemo_tmpbuf_auto_free_maybe_mark_buffer(void *buf, size_t cnt);
rb_imemo_tmpbuf_t *rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
#define RB_IMEMO_TMPBUF_PTR(v) \
((void *)(((const struct rb_imemo_tmpbuf_struct *)(v))->ptr))
+static inline void *
+rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr)
+{
+ return ((rb_imemo_tmpbuf_t *)v)->ptr = ptr;
+}
+
static inline VALUE
rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)
{
@@ -1221,7 +1229,7 @@ rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)
SafeStringValue(str);
/* create tmpbuf to keep the pointer before xmalloc */
- imemo = rb_imemo_tmpbuf_auto_free_pointer(NULL);
+ imemo = rb_imemo_tmpbuf_auto_free_pointer();
tmpbuf = (rb_imemo_tmpbuf_t *)imemo;
len = RSTRING_LEN(str);
src = RSTRING_PTR(str);