`ENV` ivars should not be accessible from ractors

The `ENV` object can have instance variables like other objects,
but they should be accessed only on the main ractor.

fix https://github.com/ruby/ruby/pull/5263#issuecomment-995585766
This commit is contained in:
Koichi Sasada 2021-12-17 14:22:14 +09:00
Родитель d524b9dec9
Коммит 37bd795cf8
2 изменённых файлов: 42 добавлений и 1 удалений

13
hash.c
Просмотреть файл

@ -6653,6 +6653,17 @@ env_dup(VALUE obj)
rb_raise(rb_eTypeError, "Cannot dup ENV, use ENV.to_h to get a copy of ENV as a hash");
}
const rb_data_type_t env_data_type = {
"ENV",
{
NULL,
RUBY_DEFAULT_FREE,
NULL,
NULL,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
};
/*
* A \Hash maps each of its unique keys to a specific value.
*
@ -7308,7 +7319,7 @@ Init_Hash(void)
* envtbl = rb_define_class("ENV", rb_cObject);
*/
origenviron = environ;
envtbl = rb_obj_alloc(rb_cObject);
envtbl = TypedData_Wrap_Struct(rb_cObject, &env_data_type, NULL);
rb_extend_object(envtbl, rb_mEnumerable);
FL_SET_RAW(envtbl, RUBY_FL_SHAREABLE);

Просмотреть файл

@ -1434,6 +1434,36 @@ class TestEnv < Test::Unit::TestCase
end;
end
def test_ivar_in_env_should_not_be_access_from_non_main_ractors
assert_ractor <<~RUBY
ENV.instance_eval{ @a = "hello" }
assert_equal "hello", ENV.instance_variable_get(:@a)
r_get = Ractor.new do
ENV.instance_variable_get(:@a)
rescue Ractor::IsolationError => e
e
end
assert_equal Ractor::IsolationError, r_get.take.class
r_get = Ractor.new do
ENV.instance_eval{ @a }
rescue Ractor::IsolationError => e
e
end
assert_equal Ractor::IsolationError, r_get.take.class
r_set = Ractor.new do
ENV.instance_eval{ @b = "hello" }
rescue Ractor::IsolationError => e
e
end
assert_equal Ractor::IsolationError, r_set.take.class
RUBY
end
if RUBY_PLATFORM =~ /bccwin|mswin|mingw/
def test_memory_leak_aset
bug9977 = '[ruby-dev:48323] [Bug #9977]'