diff --git a/ChangeLog b/ChangeLog index 3631b3f9c4..ca6c1f7b8b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Thu Apr 4 16:55:08 2013 Nobuyoshi Nakada + + * struct.c (make_struct): avoid inadvertent symbol creation. + (rb_struct_aref): ditto. + (rb_struct_aset): ditto. + Thu Apr 4 16:54:40 2013 Nobuyoshi Nakada * object.c (rb_mod_const_set): avoid inadvertent symbol creation. diff --git a/struct.c b/struct.c index 5e9f9a15a1..a3c1fb94f7 100644 --- a/struct.c +++ b/struct.c @@ -187,10 +187,11 @@ make_struct(VALUE name, VALUE members, VALUE klass) else { /* old style: should we warn? */ name = rb_str_to_str(name); - id = rb_to_id(name); - if (!rb_is_const_id(id)) { - rb_name_error(id, "identifier %s needs to be constant", StringValuePtr(name)); + if (!rb_is_const_name(name)) { + rb_name_error_str(name, "identifier %"PRIsVALUE" needs to be constant", + QUOTE(name)); } + id = rb_to_id(name); if (rb_const_defined_at(klass, id)) { rb_warn("redefining constant Struct::%s", StringValuePtr(name)); rb_mod_remove_const(klass, ID2SYM(id)); @@ -672,8 +673,16 @@ rb_struct_aref(VALUE s, VALUE idx) { long i; - if (RB_TYPE_P(idx, T_STRING) || RB_TYPE_P(idx, T_SYMBOL)) { - return rb_struct_aref_id(s, rb_to_id(idx)); + if (RB_TYPE_P(idx, T_SYMBOL)) { + return rb_struct_aref_id(s, SYM2ID(idx)); + } + else if (RB_TYPE_P(idx, T_STRING)) { + ID id = rb_check_id(&idx); + if (!id) { + rb_name_error_str(idx, "no member '%"PRIsVALUE"' in struct", + QUOTE(idx)); + } + return rb_struct_aref_id(s, id); } i = NUM2LONG(idx); @@ -739,8 +748,16 @@ rb_struct_aset(VALUE s, VALUE idx, VALUE val) { long i; - if (RB_TYPE_P(idx, T_STRING) || RB_TYPE_P(idx, T_SYMBOL)) { - return rb_struct_aset_id(s, rb_to_id(idx), val); + if (RB_TYPE_P(idx, T_SYMBOL)) { + return rb_struct_aset_id(s, SYM2ID(idx), val); + } + if (RB_TYPE_P(idx, T_STRING)) { + ID id = rb_check_id(&idx); + if (!id) { + rb_name_error_str(idx, "no member '%"PRIsVALUE"' in struct", + QUOTE(idx)); + } + return rb_struct_aset_id(s, id, val); } i = NUM2LONG(idx); diff --git a/test/-ext-/symbol/test_inadvertent_creation.rb b/test/-ext-/symbol/test_inadvertent_creation.rb index 4b9ab1062d..dde4cafffd 100644 --- a/test/-ext-/symbol/test_inadvertent_creation.rb +++ b/test/-ext-/symbol/test_inadvertent_creation.rb @@ -214,5 +214,25 @@ module Test_Symbol assert_raise(NameError) {obj.instance_variable_set(name, true)} assert_not_send([Bug::Symbol, :interned?, name]) end + + def test_struct_new + name = noninterned_name + assert_raise(NameError) {Struct.new(name)} + assert_not_send([Bug::Symbol, :interned?, name]) + end + + def test_struct_aref + s = Struct.new(:foo).new + name = noninterned_name + assert_raise(NameError) {s[name]} + assert_not_send([Bug::Symbol, :interned?, name]) + end + + def test_struct_aset + s = Struct.new(:foo).new + name = noninterned_name + assert_raise(NameError) {s[name] = true} + assert_not_send([Bug::Symbol, :interned?, name]) + end end end