From cda13c9547871b674f86282277fdcef29bad56d8 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Sat, 23 Jul 2011 23:10:48 -0700 Subject: [PATCH 2/2] Fix memory access issues with the inadvertent symbol creation removal code Switch from RSTRING_PTR to StringValuePtr so that if you pass in a random object that implements to_str, things don't fail horribly. Provide a real string for the NameErrors instead of the object originally passed in (if it was a non-String that implemented to_str). --- eval_error.c | 4 ++-- object.c | 29 ++++++++++++++++++----------- proc.c | 4 ++-- variable.c | 26 ++++++++++++++++---------- vm_method.c | 5 +++-- 5 files changed, 41 insertions(+), 27 deletions(-) diff --git a/eval_error.c b/eval_error.c index 95a9728..5ce24b5 100644 --- a/eval_error.c +++ b/eval_error.c @@ -209,8 +209,8 @@ rb_print_undef(VALUE klass, ID id, int scope) void rb_print_undef_str(VALUE klass, VALUE name) { - rb_name_error_str(name, "undefined method `%s' for %s `%s'", - RSTRING_PTR(name), + rb_name_error_str(rb_str_to_str(name), "undefined method `%s' for %s `%s'", + StringValuePtr(name), (TYPE(klass) == T_MODULE) ? "module" : "class", rb_class2name(klass)); } diff --git a/object.c b/object.c index 9248ee7..c1f4c7c 100644 --- a/object.c +++ b/object.c @@ -1780,17 +1780,19 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod) if(rb_is_const_name(name)) { if (rb_method_basic_definition_p(CLASS_OF(mod), id_const_missing)) { if (mod && rb_class_real(mod) != rb_cObject) { - rb_name_error_str(name, "uninitialized constant %s::%s", + rb_name_error_str(rb_str_to_str(name), "uninitialized constant %s::%s", rb_class2name(mod), - RSTRING_PTR(name)); + StringValuePtr(name)); } else { - rb_name_error_str(name, "uninitialized constant %s", RSTRING_PTR(name)); + rb_name_error_str(rb_str_to_str(name), "uninitialized constant %s", + StringValuePtr(name)); } } else { id = rb_to_id(name); } } else { - rb_name_error_str(name, "wrong constant name %s", RSTRING_PTR(name)); + rb_name_error_str(rb_str_to_str(name), "wrong constant name %s", + StringValuePtr(name)); } } if (!rb_is_const_id(id)) { @@ -1856,7 +1858,8 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod) return Qfalse; } else { - rb_name_error_str(name, "wrong constant name %s", RSTRING_PTR(name)); + rb_name_error_str(rb_str_to_str(name), "wrong constant name %s", + StringValuePtr(name)); } } if (!rb_is_const_id(id)) { @@ -1895,7 +1898,8 @@ rb_obj_ivar_get(VALUE obj, VALUE iv) return Qnil; } else { - rb_name_error_str(iv, "`%s' is not allowed as an instance variable name", RSTRING_PTR(iv)); + rb_name_error_str(rb_str_to_str(iv), "`%s' is not allowed as an instance variable name", + StringValuePtr(iv)); } } if (!rb_is_instance_id(id)) { @@ -1963,7 +1967,8 @@ rb_obj_ivar_defined(VALUE obj, VALUE iv) return Qfalse; } else { - rb_name_error_str(iv, "`%s' is not allowed as an instance variable name", RSTRING_PTR(iv)); + rb_name_error_str(rb_str_to_str(iv), "`%s' is not allowed as an instance variable name", + StringValuePtr(iv)); } } if (!rb_is_instance_id(id)) { @@ -1993,11 +1998,12 @@ rb_mod_cvar_get(VALUE obj, VALUE iv) if (!id) { if (rb_is_class_name(iv)) { - rb_name_error_str(iv, "uninitialized class variable %s in %s", - RSTRING_PTR(iv), rb_class2name(obj)); + rb_name_error_str(rb_str_to_str(iv), "uninitialized class variable %s in %s", + StringValuePtr(iv), rb_class2name(obj)); } else { - rb_name_error_str(iv, "`%s' is not allowed as a class variable name", RSTRING_PTR(iv)); + rb_name_error_str(rb_str_to_str(iv), "`%s' is not allowed as a class variable name", + StringValuePtr(iv)); } } if (!rb_is_class_id(id)) { @@ -2059,7 +2065,8 @@ rb_mod_cvar_defined(VALUE obj, VALUE iv) return Qfalse; } else { - rb_name_error_str(iv, "`%s' is not allowed as a class variable name", RSTRING_PTR(iv)); + rb_name_error_str(rb_str_to_str(iv), "`%s' is not allowed as a class variable name", + StringValuePtr(iv)); } } if (!rb_is_class_id(id)) { diff --git a/proc.c b/proc.c index 838a465..f258c2e 100644 --- a/proc.c +++ b/proc.c @@ -1159,8 +1159,8 @@ rb_method_name_error(VALUE klass, VALUE str) else if (RB_TYPE_P(c, T_MODULE)) { s0 = " module"; } - rb_name_error_str(str, "undefined method `%s' for%s `%s'", - RSTRING_PTR(str), s0, rb_class2name(c)); + rb_name_error_str(rb_str_to_str(str), "undefined method `%s' for%s `%s'", + StringValuePtr(str), s0, rb_class2name(c)); } /* diff --git a/variable.c b/variable.c index bbcd2fd..22bde4c 100644 --- a/variable.c +++ b/variable.c @@ -636,7 +636,8 @@ rb_f_untrace_var(int argc, VALUE *argv) rb_scan_args(argc, argv, "11", &var, &cmd); id = rb_check_id(var); if (!id) { - rb_name_error_str(var, "undefined global variable %s", RSTRING_PTR(var)); + rb_name_error_str(rb_str_to_str(var), "undefined global variable %s", + StringValuePtr(var)); } if (!st_lookup(rb_global_tbl, (st_data_t)id, &data)) { rb_name_error(id, "undefined global variable %s", rb_id2name(id)); @@ -1312,10 +1313,12 @@ rb_obj_remove_instance_variable(VALUE obj, VALUE name) rb_check_frozen(obj); if (!id) { if (rb_is_instance_name(name)) { - rb_name_error_str(name, "instance variable %s not defined", RSTRING_PTR(name)); + rb_name_error_str(rb_str_to_str(name), "instance variable %s not defined", + StringValuePtr(name)); } else { - rb_name_error_str(name, "`%s' is not allowed as an instance variable name", RSTRING_PTR(name)); + rb_name_error_str(rb_str_to_str(name), "`%s' is not allowed as an instance variable name", + StringValuePtr(name)); } } if (!rb_is_instance_id(id)) { @@ -1692,11 +1695,12 @@ rb_mod_remove_const(VALUE mod, VALUE name) if (!id) { if (rb_is_const_name(name)) { - rb_name_error_str(name, "constant %s::%s not defined", - rb_class2name(mod), RSTRING_PTR(name)); + rb_name_error_str(rb_str_to_str(name), "constant %s::%s not defined", + rb_class2name(mod), StringValuePtr(name)); } else { - rb_name_error_str(name, "`%s' is not allowed as a constant name", RSTRING_PTR(name)); + rb_name_error_str(rb_str_to_str(name), "`%s' is not allowed as a constant name", + StringValuePtr(name)); } } if (!rb_is_const_id(id)) { @@ -1979,7 +1983,8 @@ set_const_visibility(VALUE mod, int argc, VALUE *argv, rb_const_flag_t flag) val = argv[i]; id = rb_check_id(val); if (!id) { - rb_name_error_str(val, "constant %s::%s not defined", rb_class2name(mod), RSTRING_PTR(val)); + rb_name_error_str(rb_str_to_str(val), "constant %s::%s not defined", + rb_class2name(mod), StringValuePtr(val)); } if (RCLASS_CONST_TBL(mod) && st_lookup(RCLASS_CONST_TBL(mod), (st_data_t)id, &v)) { ((rb_const_entry_t*)v)->flag = flag; @@ -2219,11 +2224,12 @@ rb_mod_remove_cvar(VALUE mod, VALUE name) if (!id) { if (rb_is_class_name(name)) { - rb_name_error_str(name, "class variable %s not defined for %s", - RSTRING_PTR(name), rb_class2name(mod)); + rb_name_error_str(rb_str_to_str(name), "class variable %s not defined for %s", + StringValuePtr(name), rb_class2name(mod)); } else { - rb_name_error_str(name, "wrong class variable name %s", RSTRING_PTR(name)); + rb_name_error_str(rb_str_to_str(name), "wrong class variable name %s", + StringValuePtr(name)); } } if (!rb_is_class_id(id)) { diff --git a/vm_method.c b/vm_method.c index c8a876b..37316b6 100644 --- a/vm_method.c +++ b/vm_method.c @@ -476,8 +476,9 @@ rb_mod_remove_method(int argc, VALUE *argv, VALUE mod) v = argv[i]; id = rb_check_id(v); if (!id) { - rb_name_error_str(v, "method `%s' not defined in %s", - RSTRING_PTR(v), rb_class2name(mod)); + rb_name_error_str(rb_str_to_str(v), "method `%s' not defined in %s", + StringValuePtr(v), + rb_class2name(mod)); } remove_method(mod, id); } -- 1.7.5