summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--test/-ext-/symbol/test_inadvertent_creation.rb28
-rw-r--r--thread.c21
3 files changed, 49 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 3697bfc704..f63bb4878d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Thu Apr 4 14:37:07 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * thread.c (rb_thread_aref): avoid inadvertent symbol creation.
+ (rb_thread_variable_get): ditto.
+ (rb_thread_key_p): ditto.
+ (rb_thread_variable_p): ditto.
+
Thu Apr 4 11:33:57 2013 NARUSE, Yui <naruse@ruby-lang.org>
* ext/openssl/ossl_bn.c (ossl_bn_to_i): Use bn2hex to speed up.
diff --git a/test/-ext-/symbol/test_inadvertent_creation.rb b/test/-ext-/symbol/test_inadvertent_creation.rb
index 7c0aaa89f0..96a0dafc4b 100644
--- a/test/-ext-/symbol/test_inadvertent_creation.rb
+++ b/test/-ext-/symbol/test_inadvertent_creation.rb
@@ -159,5 +159,33 @@ module Test_Symbol
assert_equal(name, e.name)
assert_equal([Feature5112], e.args)
end
+
+ def test_thread_aref
+ Thread.current[:test] = nil
+ name = noninterned_name
+ assert_nil(Thread.current[name])
+ assert_not_send([Bug::Symbol, :interned?, name])
+ end
+
+ def test_thread_key?
+ Thread.current[:test] = nil
+ name = noninterned_name
+ assert_not_send([Thread.current, :key?, name])
+ assert_not_send([Bug::Symbol, :interned?, name])
+ end
+
+ def test_thread_variable_get
+ Thread.current.thread_variable_set(:test, nil)
+ name = noninterned_name
+ assert_nil(Thread.current.thread_variable_get(name))
+ assert_not_send([Bug::Symbol, :interned?, name])
+ end
+
+ def test_thread_variable?
+ Thread.current.thread_variable_set(:test, nil)
+ name = noninterned_name
+ assert_not_send([Thread.current, :thread_variable?, name])
+ assert_not_send([Bug::Symbol, :interned?, name])
+ end
end
end
diff --git a/thread.c b/thread.c
index 7b343a522d..350768f9b4 100644
--- a/thread.c
+++ b/thread.c
@@ -2784,9 +2784,11 @@ rb_thread_local_aref(VALUE thread, ID id)
*/
static VALUE
-rb_thread_aref(VALUE thread, VALUE id)
+rb_thread_aref(VALUE thread, VALUE key)
{
- return rb_thread_local_aref(thread, rb_to_id(id));
+ ID id = rb_check_id(&key);
+ if (!id) return Qnil;
+ return rb_thread_local_aref(thread, id);
}
VALUE
@@ -2862,10 +2864,11 @@ rb_thread_aset(VALUE self, VALUE id, VALUE val)
*/
static VALUE
-rb_thread_variable_get(VALUE thread, VALUE id)
+rb_thread_variable_get(VALUE thread, VALUE key)
{
VALUE locals;
rb_thread_t *th;
+ ID id = rb_check_id(&key);
GetThreadPtr(thread, th);
@@ -2873,8 +2876,9 @@ rb_thread_variable_get(VALUE thread, VALUE id)
rb_raise(rb_eSecurityError, "Insecure: can't access thread locals");
}
+ if (!id) return Qnil;
locals = rb_iv_get(thread, "locals");
- return rb_hash_aref(locals, ID2SYM(rb_to_id(id)));
+ return rb_hash_aref(locals, ID2SYM(id));
}
/*
@@ -2922,11 +2926,11 @@ static VALUE
rb_thread_key_p(VALUE self, VALUE key)
{
rb_thread_t *th;
- ID id = rb_to_id(key);
+ ID id = rb_check_id(&key);
GetThreadPtr(self, th);
- if (!th->local_storage) {
+ if (!id || !th->local_storage) {
return Qfalse;
}
if (st_lookup(th->local_storage, id, 0)) {
@@ -3043,13 +3047,16 @@ static VALUE
rb_thread_variable_p(VALUE thread, VALUE key)
{
VALUE locals;
+ ID id = rb_check_id(&key);
+
+ if (!id) return Qfalse;
locals = rb_iv_get(thread, "locals");
if (!RHASH(locals)->ntbl)
return Qfalse;
- if (st_lookup(RHASH(locals)->ntbl, ID2SYM(rb_to_id(key)), 0)) {
+ if (st_lookup(RHASH(locals)->ntbl, ID2SYM(id), 0)) {
return Qtrue;
}