Unquote Gem.ruby when spawning it as a separate argv element#9695
Open
hsbt wants to merge 1 commit into
Open
Conversation
Gem.ruby wraps the interpreter path in double quotes when it contains whitespace. That suits single-string shell commands but breaks the multi-argument spawns that pass it as its own argv element. Under an install prefix containing a space, `gem update --system`, mkrf extension builds, `gem push` attestation, and the bundler auto-switch all fail to spawn with exit 127. Split it with Shellwords, matching the existing `Gem::Ext::Builder.ruby` idiom. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Gem.rubywraps the interpreter path in double quotes when it contains whitespace, which is a historical convention for interpolating it into single-string shell commands. Four call sites pass it as a separate argv element to a non-shell spawn, where the embedded quotes become part of the file name and the spawn fails with exit 127 /Errno::ENOENT. Under an installation prefix containing a space (for exampleC:\Program Files), this breaksgem update --systeminGem::Commands::UpdateCommand#install_rubygems, mkrf extension builds inGem::Ext::RakeBuilder.build, the attestation signing spawn inGem::Commands::PushCommand#attest!(which then silently falls back to an unsigned push through its rescue), and the bundler version auto-switch inBundler::SelfManager#restart_with. On Windows the auto-switch takes this path by default because$PROGRAM_NAMEis an extensionless script for whichFile.executable?returns false.This fixes each site by splitting
Gem.rubywithShellwords, following the existing idiom inGem::Ext::Builder.ruby("Gem.ruby is quoted if it contains whitespace").Gem::Ext::RakeBuildereven had both patterns in the same method: the rake invocation on line 26 already used the shellsplit form while the mkrf spawn three lines above did not. The return value ofGem.rubyitself is unchanged since shebang and batch file generation depend on the quoted form.Reproduction with a mswin Ruby 4.0.5 copied to
V:\tmp\ruby with space\:Manual end-to-end verification on Windows with the patched lib loaded under that space-path Ruby: the mkrf_conf spawn in
RakeBuilder.buildnow runs (sentinel file written by the child proves the interpreter started), the patchedsystem(*Shellwords.split(Gem.ruby), "--disable-gems", ...)call shape frominstall_rubygemssucceeds, and the old call shape still returnsnilconfirming the original failure:Each site gets a unit test that stubs
Gem.rubyto a quoted value and asserts the assembled command has an unquoted interpreter argv element.A related but distinct issue remains in
Bundler::SharedHelpers#set_rubyopt, which injects an unquoted-r<absolute path>into the space-separatedRUBYOPT.RUBYOPThas no quoting mechanism, so that needs a different approach and will be addressed separately.🤖 Generated with Claude Code