-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Fix Namespace RubyGems isolation issue #13313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Ensures each namespace has its own independent RubyGems environment by removing any inherited Gem constant before loading RubyGems in each namespace. This prevents the sharing of RubyGems state across namespaces, fixing version conflicts between them. Fixes Bug #21324
Ensures each namespace has its own independent RubyGems environment by removing any inherited Gem constant before loading RubyGems in each namespace. This prevents the sharing of RubyGems state across namespaces, fixing version conflicts between them.
Couldn't these be extracted as a function? |
@@ -567,6 +567,22 @@ namespace_initialize(VALUE namespace) | |||
|
|||
setup_pushing_loading_namespace(ns); | |||
|
|||
// Initialize RubyGems for this new namespace, if gems are enabled. | |||
// We check if Gem exists in the main namespace as an indicator | |||
if (rb_const_defined(rb_cObject, rb_intern("Gem"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check doesn't check Gem
in main, but the current namespace (the namespace calling Namespace.new
in). So the comment above is misleading.
@@ -1007,6 +1023,18 @@ rb_initialize_main_namespace(void) | |||
rb_const_set(rb_cNamespace, rb_intern("MAIN"), main_ns); | |||
|
|||
vm->main_namespace = th->ns = main_namespace = ns; | |||
|
|||
// If RubyGems was loaded in the root namespace during boot, | |||
// remove it and load a fresh copy in the main namespace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The line th->ns = ns
specifies the main namespace as the current namespace. So the cleaning RubyGems status should be done above the line.
The created namespace is copied from the root namespace, so we need to check if the |
Do we need to load RubyGems explicitly in new |
I'm not familiar to RubyGems itself, but it seems better to clear RubyGems's internal status than to remove-and-require |
It's not a correct fix, see https://bugs.ruby-lang.org/issues/21324#note-6 |
Ensure independent RubyGems environments per namespace
This fix resolves an issue where the Namespace feature fails to properly isolate RubyGems state. In the current implementation, RubyGems gets loaded into the root namespace and is shared across all user namespaces. This causes gem versions loaded in one namespace to affect others, leading to
Gem::LoadError
problems.The fix explicitly removes any inherited
Gem
constant during main namespace and newly created namespace initialisation, then loads a fresh RubyGems environment in each namespace. This allows each namespace to manage its own gem dependencies without conflicts between namespaces.Fixes Bug #21324.