* enum.c (enum_count): call #size using rb_funcall_no_recursive()

to prevent infinite recursive calls.  [ruby-core:24794]

* vm_eval.c (rb_funcall_no_recursive): utility function to check
  direct recursive call.

* vm_eval.c (rb_check_funcall): move from eval.c. [refactoring]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25560 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2009-10-29 17:16:05 +00:00
Родитель 2f2e8455e3
Коммит 7f2ef1a96e
4 изменённых файлов: 56 добавлений и 34 удалений

Просмотреть файл

@ -1,3 +1,13 @@
Fri Oct 30 02:11:36 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
* enum.c (enum_count): call #size using rb_funcall_no_recursive()
to prevent infinite recursive calls. [ruby-core:24794]
* vm_eval.c (rb_funcall_no_recursive): utility function to check
direct recursive call.
* vm_eval.c (rb_check_funcall): move from eval.c. [refactoring]
Thu Oct 29 18:37:02 2009 NARUSE, Yui <naruse@ruby-lang.org>
* encoding.c (Init_Encoding): revert previous commit.

6
enum.c
Просмотреть файл

@ -119,6 +119,8 @@ count_all_i(VALUE i, VALUE memop, int argc, VALUE *argv)
return Qnil;
}
extern VALUE rb_funcall_no_recursive(VALUE, ID, int, VALUE*, VALUE (*)());
/*
* call-seq:
* enum.count => int
@ -150,8 +152,8 @@ enum_count(int argc, VALUE *argv, VALUE obj)
}
else {
VALUE tmp;
tmp = rb_check_funcall(obj, id_size, 0, 0);
tmp = rb_funcall_no_recursive(obj, id_size, 0, 0, enum_count);
if (tmp != Qundef) return tmp;
func = count_all_i;
}

32
eval.c
Просмотреть файл

@ -492,38 +492,6 @@ rb_f_raise(int argc, VALUE *argv)
return Qnil; /* not reached */
}
struct rescue_funcall_args {
VALUE obj;
ID id;
int argc;
VALUE *argv;
};
static VALUE
check_funcall(struct rescue_funcall_args *args)
{
return rb_funcall2(args->obj, args->id, args->argc, args->argv);
}
static VALUE
check_failed(VALUE data)
{
return data;
}
VALUE
rb_check_funcall(VALUE obj, ID id, int argc, VALUE *argv)
{
struct rescue_funcall_args args;
args.obj = obj;
args.id = id;
args.argc = argc;
args.argv = argv;
return rb_rescue2(check_funcall, (VALUE)&args, check_failed, Qundef,
rb_eNoMethodError, (VALUE)0);
}
static VALUE
make_exception(int argc, VALUE *argv, int isstr)
{

Просмотреть файл

@ -536,6 +536,48 @@ rb_funcall3(VALUE recv, ID mid, int argc, const VALUE *argv)
return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
}
struct rescue_funcall_args {
VALUE obj;
ID id;
int argc;
VALUE *argv;
};
static VALUE
check_funcall(struct rescue_funcall_args *args)
{
return rb_funcall2(args->obj, args->id, args->argc, args->argv);
}
static VALUE
check_failed(VALUE data)
{
return data;
}
VALUE
rb_check_funcall(VALUE obj, ID id, int argc, VALUE *argv)
{
struct rescue_funcall_args args;
args.obj = obj;
args.id = id;
args.argc = argc;
args.argv = argv;
return rb_rescue2(check_funcall, (VALUE)&args, check_failed, Qundef,
rb_eNoMethodError, (VALUE)0);
}
VALUE
rb_funcall_no_recursive(VALUE obj, ID id, int argc, VALUE *argv, VALUE (*func)())
{
const rb_method_entry_t *me = rb_method_entry(CLASS_OF(obj), id);
if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC &&
me->def->body.cfunc.func == func)
return Qundef;
return rb_check_funcall(obj, id, argc, argv);
}
static VALUE
send_internal(int argc, const VALUE *argv, VALUE recv, int scope)
{