ruby-changes:47001
From: nobu <ko1@a...>
Date: Mon, 19 Jun 2017 23:36:26 +0900 (JST)
Subject: [ruby-changes:47001] nobu:r59116 (trunk): test for [Bug #12670]
nobu 2017-06-19 23:36:17 +0900 (Mon, 19 Jun 2017) New Revision: 59116 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59116 Log: test for [Bug #12670] heap corruption by deferred free. Modified files: trunk/ext/-test-/typeddata/typeddata.c trunk/test/-ext-/typeddata/test_typeddata.rb Index: ext/-test-/typeddata/typeddata.c =================================================================== --- ext/-test-/typeddata/typeddata.c (revision 59115) +++ ext/-test-/typeddata/typeddata.c (revision 59116) @@ -2,19 +2,43 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/typeddata/typeddata.c#L2 static const rb_data_type_t test_data = { "typed_data", + {NULL, ruby_xfree, NULL}, + NULL, NULL, + 0/* deferred free */, }; static VALUE +test_alloc(VALUE klass) +{ + char *p; + return TypedData_Make_Struct(klass, char, &test_data, p); +} + +static VALUE test_check(VALUE self, VALUE obj) { rb_check_typeddata(obj, &test_data); return obj; } +static VALUE +test_make(VALUE klass, VALUE num) +{ + unsigned long i, n = NUM2UINT(num); + + for (i = 0; i < n; i++) { + test_alloc(klass); + } + + return Qnil; +} + void Init_typeddata(void) { VALUE mBug = rb_define_module("Bug"); VALUE klass = rb_define_class_under(mBug, "TypedData", rb_cData); + rb_define_alloc_func(klass, test_alloc); rb_define_singleton_method(klass, "check", test_check, 1); + rb_define_singleton_method(klass, "make", test_make, 1); } Index: test/-ext-/typeddata/test_typeddata.rb =================================================================== --- test/-ext-/typeddata/test_typeddata.rb (revision 59115) +++ test/-ext-/typeddata/test_typeddata.rb (revision 59116) @@ -17,4 +17,15 @@ class Test_TypedData < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/-ext-/typeddata/test_typeddata.rb#L17 obj = eval("class C\u{1f5ff}; self; end").new assert_raise_with_message(TypeError, /C\u{1f5ff}/) {Bug::TypedData.check(obj)} end + + def test_deferred_free + assert_ruby_status([], "#{<<-"begin;"}\n#{<<-"end;"}") + require "-test-/typeddata" + begin; + n = 1 << 20 + Bug::TypedData.make(n) + end; + rescue MiniTest::Assertion => e + skip e.message + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/