Issue #5801 has been updated by satoshi shiba.


Enumerable#grep ??????????????????????????????
以?????????????? Segv ????????????????

enum.c ????XX_i ???????形????第?????? C ???
???????????????????????????????????????????
??????????????????????????????????

# ????????
=begin
class A
  include Enumerable
  def each(&b)
    $block = b
    yield
  end
end
puts A.new.grep(//)
100.times{$block.call}
=end


static VALUE
grep_i(VALUE i, VALUE args, int argc, VALUE *argv)
{
    VALUE *arg = (VALUE *)args; /* arg ??? C ???????????????? */
    ENUM_WANT_SVALUE();

    if (RTEST(rb_funcall(arg[0], id_eqq, 1, i))) {
        rb_ary_push(arg[1], i);
    }
    return Qnil;
}

----------------------------------------
Bug #5801: Enumerable#take_while ??? proc ???????????使?????? Segv
https://bugs.ruby-lang.org/issues/5801

Author: satoshi shiba
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 1.9.3
ruby -v: ruby 1.9.3p6 (2011-12-20 revision 34080) [i686-linux]


???????????????

?????????????????????Enumerable#take_while ??? Proc ???
????????使?????? Segv ?????????????????

# ????????
=begin
class A
  include Enumerable
  def each(&b)
    $block = b
    yield
  end
end
puts A.new.take_while{true}
100.times{$block.call}
=end


$block ?????take_while ?????使??????? take_while_i (enum.c)
??? C ??? Proc ?????????????????????? Proc ??????????????????
??????????????????????take_while ?????????使???
????????? Segv ????????????????

?????????????????????enum_take_while ??? take_while_i ????
take_while ???????????????????????????????????????????????
渡???????????????????????????????????

/* enum_take_while ??? take_while_i */
static VALUE
enum_take_while(VALUE obj)
{
  VALUE ary;
  RETURN_ENUMERATOR(obj, 0, 0);
  ary = rb_ary_new();
  rb_block_call(obj, id_each, 0, 0, take_while_i, (VALUE)&ary /* <= ???? */);
  return ary;
}

static VALUE
take_while_i(VALUE i, VALUE *ary /* <= ???? */, int argc, VALUE *argv)
{
  if (!RTEST(enum_yield(argc, argv))) rb_iter_break();
  rb_ary_push(*ary /* <= ???? */, enum_values_pack(argc, argv));
  return Qnil;
}


enum_take_while ???? rb_block_call ???????????????? &ary ???
????????渡?????????????????ary ??? C ?????????????????????????
C ?????????????????????????????????????????????take_while ???
???????????????????????????????????? Proc ?????? take_while_i
???????????????????*ary ???????????????????????????? Segv ???
?????????????????????????????????

以????????????????????????????????????????確???????????????
????????????????????????????幸??????????
??????????????????????????????????

/* ????????? */
Index: enum.c
===================================================================
--- enum.c      (revision 34107)
+++ enum.c      (working copy)
@@ -2053,7 +2053,7 @@
 take_while_i(VALUE i, VALUE *ary, int argc, VALUE *argv)
 {
     if (!RTEST(enum_yield(argc, argv))) rb_iter_break();
-    rb_ary_push(*ary, enum_values_pack(argc, argv));
+    rb_ary_push((VALUE)ary, enum_values_pack(argc, argv));
     return Qnil;
 }

@@ -2079,7 +2079,7 @@

     RETURN_ENUMERATOR(obj, 0, 0);
     ary = rb_ary_new();
-    rb_block_call(obj, id_each, 0, 0, take_while_i, (VALUE)&ary);
+    rb_block_call(obj, id_each, 0, 0, take_while_i, ary);
     return ary;
 }



-- 
http://redmine.ruby-lang.org