Feature #5072 » 0002-Avoid-inadvertent-symbol-creation-in-reflection-meth.patch
| 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; | ||