Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

Conversation

jsxs0
Copy link

@jsxs0 jsxs0 commented May 13, 2025

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.

jsxs0 added 4 commits May 13, 2025 15:41
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.
@nobu
Copy link
Member

nobu commented May 13, 2025

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")))
Copy link
Contributor

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
Copy link
Contributor

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.

@tagomoris
Copy link
Contributor

The created namespace is copied from the root namespace, so we need to check if the Gem exists in the root namespace.
The way to do it is... hmm, accessing RCLASSEXT_CONST_TBL(RCLASS_EXT_PRIME(rb_cObject)) is the only way for now. It might be good to add a function to do that specifically.

@simi
Copy link
Contributor

simi commented May 13, 2025

Do we need to load RubyGems explicitly in new Namespace if present in root one?

@tagomoris
Copy link
Contributor

I'm not familiar to RubyGems itself, but it seems better to clear RubyGems's internal status than to remove-and-require rubygems.
And I guess this code doesn't work well because the .rb files of rubygems are already included in $LOADED_FEATURES.

@eregon
Copy link
Member

eregon commented May 13, 2025

It's not a correct fix, see https://bugs.ruby-lang.org/issues/21324#note-6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants