Project

General

Profile

Feature #5072 » 0002-Avoid-inadvertent-symbol-creation-in-reflection-meth.patch

jeremyevans0 (Jeremy Evans), 07/22/2011 08:02 AM

View differences:

include/ruby/ruby.h
ID rb_intern2(const char*, long);
ID rb_intern_str(VALUE str);
const char *rb_id2name(ID);
int rb_check_id(VALUE, ID*);
ID rb_to_id(VALUE);
VALUE rb_id2str(ID);
object.c
else {
rb_scan_args(argc, argv, "11", &name, &recur);
}
id = rb_to_id(name);
if(!rb_check_id(name, &id))
return Qfalse;
if (!rb_is_const_id(id)) {
rb_name_error(id, "wrong constant name %s", rb_id2name(id));
}
......
static VALUE
rb_obj_ivar_defined(VALUE obj, VALUE iv)
{
ID id = rb_to_id(iv);
ID id;
if(!rb_check_id(iv, &id))
return Qfalse;
if (!rb_is_instance_id(id)) {
rb_name_error(id, "`%s' is not allowed as an instance variable name", rb_id2name(id));
......
static VALUE
rb_mod_cvar_defined(VALUE obj, VALUE iv)
{
ID id = rb_to_id(iv);
ID id;
if(!rb_check_id(iv, &id))
return Qfalse;
if (!rb_is_class_id(id)) {
rb_name_error(id, "`%s' is not allowed as a class variable name", rb_id2name(id));
parse.y
return is_junk_id(id);
}
int
rb_check_id(VALUE name, ID *id)
{
VALUE tmp;
switch (TYPE(name)) {
default:
tmp = rb_check_string_type(name);
if (NIL_P(tmp)) {
tmp = rb_inspect(name);
rb_raise(rb_eTypeError, "%s is not a symbol",
RSTRING_PTR(tmp));
}
name = tmp;
/* fall through */
case T_STRING:
return st_lookup(global_symbols.sym_id, (st_data_t)name, id);
case T_SYMBOL:
*id = SYM2ID(name);
return 1;
}
return 0; /* not reached */
}
#endif /* !RIPPER */
static void
test/ruby/test_parse.rb
assert_equal(':"foo=="', "foo==".intern.inspect)
end
def test_no_inadvertent_symbol_creation
s = "gadzooks"
{:respond_to? =>"#{s}1", :method_defined? =>"#{s}2",
:public_method_defined? =>"#{s}3", :private_method_defined? =>"#{s}4",
:protected_method_defined? =>"#{s}5", :const_defined? =>"A#{s}",
:instance_variable_defined? =>"@#{s}", :class_variable_defined? =>"@@#{s}"
}.each do |meth, str|
Object.send(meth, str)
assert !Symbol.all_symbols.any?{|sym| sym.to_s == str}
end
end
def test_all_symbols
x = Symbol.all_symbols
assert_kind_of(Array, x)
vm_method.c
static VALUE
rb_mod_method_defined(VALUE mod, VALUE mid)
{
if (!rb_method_boundp(mod, rb_to_id(mid), 1)) {
ID id;
if(!rb_check_id(mid, &id))
return Qfalse;
if (!rb_method_boundp(mod, id, 1)) {
return Qfalse;
}
return Qtrue;
......
static VALUE
rb_mod_public_method_defined(VALUE mod, VALUE mid)
{
return check_definition(mod, rb_to_id(mid), NOEX_PUBLIC);
ID id;
if(!rb_check_id(mid, &id))
return Qfalse;
return check_definition(mod, id, NOEX_PUBLIC);
}
/*
......
static VALUE
rb_mod_private_method_defined(VALUE mod, VALUE mid)
{
return check_definition(mod, rb_to_id(mid), NOEX_PRIVATE);
ID id;
if(!rb_check_id(mid, &id))
return Qfalse;
return check_definition(mod, mid, NOEX_PRIVATE);
}
/*
......
static VALUE
rb_mod_protected_method_defined(VALUE mod, VALUE mid)
{
return check_definition(mod, rb_to_id(mid), NOEX_PROTECTED);
ID id;
if(!rb_check_id(mid, &id))
return Qfalse;
return check_definition(mod, id, NOEX_PROTECTED);
}
int
......
ID id;
rb_scan_args(argc, argv, "11", &mid, &priv);
id = rb_to_id(mid);
if(!rb_check_id(mid, &id))
return Qfalse;
if (basic_obj_respond_to(obj, id, !RTEST(priv)))
return Qtrue;
return Qfalse;
(2-2/3)