summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-02-15 07:18:22 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-02-15 07:18:22 +0000
commit31e0a51652967bf6c260176101a372faabe489a7 (patch)
tree52ff80901166ffc2d0388d502bdbdf576c586320
parentab530f056c7e45aa711a736790fb448bbdce19e7 (diff)
merge revision(s) r40101:
* struct.c (make_struct): avoid inadvertent symbol creation. (rb_struct_aref): ditto. (rb_struct_aset): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@44968 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog6
-rw-r--r--struct.c31
-rw-r--r--test/-ext-/symbol/test_inadvertent_creation.rb20
-rw-r--r--version.h2
4 files changed, 51 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 5e59f6cb28..29e2b04871 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Sat Feb 15 16:08:26 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * struct.c (make_struct): avoid inadvertent symbol creation.
+ (rb_struct_aref): ditto.
+ (rb_struct_aset): ditto.
+
Sat Feb 15 15:32:46 2014 Shugo Maeda <shugo@ruby-lang.org>
* vm_insnhelper.c (vm_call_method): should check ci->me->flag of
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 7c0aaa89f0..6447c955c5 100644
--- a/test/-ext-/symbol/test_inadvertent_creation.rb
+++ b/test/-ext-/symbol/test_inadvertent_creation.rb
@@ -159,5 +159,25 @@ module Test_Symbol
assert_equal(name, e.name)
assert_equal([Feature5112], e.args)
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
diff --git a/version.h b/version.h
index 96b9f0857c..5266408cdc 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.0.0"
#define RUBY_RELEASE_DATE "2014-02-15"
-#define RUBY_PATCHLEVEL 403
+#define RUBY_PATCHLEVEL 404
#define RUBY_RELEASE_YEAR 2014
#define RUBY_RELEASE_MONTH 2