Skip to content

Commit 5ea8e04

Browse files
authored
Merge pull request #9696 from ruby/set-rubyopt-space-safe
Avoid space-containing absolute path in RUBYOPT
2 parents 3e9c07d + 2d50d82 commit 5ea8e04

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

lib/bundler/shared_helpers.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,12 @@ def set_path
347347

348348
def set_rubyopt
349349
rubyopt = [ENV["RUBYOPT"]].compact
350-
setup_require = "-r#{File.expand_path("setup", __dir__)}"
350+
setup_path = File.expand_path("setup", __dir__)
351+
# RUBYOPT is split on whitespace with no quoting mechanism, so an
352+
# absolute path containing spaces would be torn apart. Fall back to
353+
# requiring by feature name; set_rubylib puts our lib directory first
354+
# on the child's load path.
355+
setup_require = /\s/.match?(setup_path) ? "-rbundler/setup" : "-r#{setup_path}"
351356
return if !rubyopt.empty? && rubyopt.first.include?(setup_require)
352357
rubyopt.unshift setup_require
353358
Bundler::SharedHelpers.set_env "RUBYOPT", rubyopt.join(" ")

spec/bundler/shared_helpers_spec.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,34 @@
399399
it_behaves_like "ENV['RUBYOPT'] gets set correctly"
400400
end
401401

402+
context "when bundler install path contains whitespace" do
403+
let(:install_path) { "/opt/ruby with space/lib" }
404+
405+
before do
406+
allow(File).to receive(:expand_path).and_return("#{install_path}/bundler/setup")
407+
allow(Gem).to receive(:bin_path).and_return("#{install_path}/bundler/setup")
408+
end
409+
410+
# RUBYOPT is split on whitespace with no quoting mechanism, so an
411+
# absolute -r path containing spaces would make every child ruby fail
412+
# to boot with "invalid switch in RUBYOPT".
413+
it "requires bundler/setup by feature name instead of absolute path" do
414+
subject.set_bundle_environment
415+
expect(ENV["RUBYOPT"].split(" ")).to start_with("-rbundler/setup")
416+
end
417+
418+
it "does not inject the space-containing path into RUBYOPT" do
419+
subject.set_bundle_environment
420+
expect(ENV["RUBYOPT"]).not_to include(install_path)
421+
end
422+
423+
it "is idempotent" do
424+
subject.set_bundle_environment
425+
subject.set_bundle_environment
426+
expect(ENV["RUBYOPT"].split(" ").grep(%r{\A-r.*bundler/setup\z}).length).to eq(1)
427+
end
428+
end
429+
402430
context "ENV['RUBYLIB'] does not exist" do
403431
before { ENV.delete("RUBYLIB") }
404432

0 commit comments

Comments
 (0)