aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--object.c7
-rw-r--r--test/ruby/test_object.rb10
3 files changed, 20 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index d4e1c38cd4..a24581fbb4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Sep 3 16:56:07 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * object.c (rb_obj_copy_ivar): allocate no memory for empty
+ instance variables. [ruby-core:64700] [Bug #10191]
+
Wed Sep 3 12:05:17 2014 Tanaka Akira <akr@fsij.org>
* process.c (retry_fork_async_signal_safe): Use vfork() if available.
diff --git a/object.c b/object.c
index b994539350..44cb842f0d 100644
--- a/object.c
+++ b/object.c
@@ -270,8 +270,11 @@ rb_obj_copy_ivar(VALUE dest, VALUE obj)
}
else {
long len = ROBJECT(obj)->as.heap.numiv;
- VALUE *ptr = ALLOC_N(VALUE, len);
- MEMCPY(ptr, ROBJECT(obj)->as.heap.ivptr, VALUE, len);
+ VALUE *ptr = 0;
+ if (len > 0) {
+ ptr = ALLOC_N(VALUE, len);
+ MEMCPY(ptr, ROBJECT(obj)->as.heap.ivptr, VALUE, len);
+ }
ROBJECT(dest)->as.heap.ivptr = ptr;
ROBJECT(dest)->as.heap.numiv = len;
ROBJECT(dest)->as.heap.iv_index_tbl = ROBJECT(obj)->as.heap.iv_index_tbl;
diff --git a/test/ruby/test_object.rb b/test/ruby/test_object.rb
index 4573dc859e..e79913ead0 100644
--- a/test/ruby/test_object.rb
+++ b/test/ruby/test_object.rb
@@ -811,4 +811,14 @@ class TestObject < Test::Unit::TestCase
assert_raise_with_message(TypeError, "can't convert Array into Integer") {Integer([42])}
assert_raise_with_message(TypeError, 'no implicit conversion of Array into Integer') {[].first([42])}
end
+
+ def test_copied_ivar_memory_leak
+ bug10191 = '[ruby-core:64700] [Bug #10191]'
+ assert_no_memory_leak([], <<-"end;", <<-"end;", bug10191, rss: true)
+ def (a = Object.new).set; @v = nil; end
+ num = 500_000
+ end;
+ num.times {a.clone.set}
+ end;
+ end
end