[agent] Found by the scheduled Bundler (RubyGems) bug-hunt routine (ledger #316).
Summary
The ruby crawler finds the global gem homes by running gem env gemdir and gem env gempath through SystemCommandRunner.run("gem", …), which is std::process::Command::new("gem"). On Windows, Command::new resolves only gem.exe on PATH. RubyInstaller ships gem.cmd plus an extensionless gem script and no gem.exe, so the spawn fails, both answers come back None, and the crawler falls back to its hard-coded list (~/.gem/ruby/*, ~/.rbenv, ~/.rvm, /usr/lib/ruby/gems, …). None of those cover a RubyInstaller gem dir (C:\Ruby3x-x64\lib\ruby\gems\3.x.0, or D:\a\_temp\rubyinstaller-… in CI) or the RubyGems ≥ 3.5 user dir (~/.local/share/gem/ruby/3.x.0).
As a result:
scan -g exits 0 and reports scannedPackages: 0, so global gems with patches are silently missing from the report.
get -g <uuid> fails with The targeted manifest patch matched no installed package: pkg:gem/colorize@0.8.1, even though the gem is installed globally.
vex -g omits the purl (package_not_found).
- On Ruby 2.7 (user dir
~/.gem/ruby/2.7.0, which the fallback list happens to cover), -g sees only the user-install copy. get -g reports success while the system copy in the RubyInstaller gem dir stays unpatched (Using ruby gem paths at: C:\Users\runneradmin\.gem\ruby\2.7.0\gems).
--global-prefix <gemdir>\gems works on the same runners (the copy is found), which confirms that discovery is the broken step and not the patching.
Impact
Global Windows gem installs are invisible to the documented -g flow on current RubyInstaller Rubies, and scan -g gives no hint (exit 0, empty result). The same gem env lookup feeds local mode's non-deployment fallback (a bundle install without BUNDLE_PATH installs into the gem dir), so Windows Bundler projects on system gems are probably affected too. I haven't verified that separately.
Repro (windows-latest, ruby/setup-ruby, Git Bash; a mock patch API on 127.0.0.1 serves one patch for colorize@0.8.1)
gem install colorize -v 0.8.1 --no-document
gem install --user-install colorize -v 0.8.1 --no-document
ls "$(dirname "$(which gem)")" | grep '^gem' # -> gem, gem.cmd (no gem.exe)
SP="socket-patch --api-url http://127.0.0.1:18999 --api-token fake --org org"
$SP scan -g --ecosystems gem --json # "scannedPackages": 0, colorize not listed, exit 0
$SP get -g 11111111-2222-4333-8444-555555555555 --yes
# Error: The targeted manifest patch matched no installed package:
# - pkg:gem/colorize@0.8.1
# Summary: 0 of 1 targeted patch applied, 0 already patched, 1 not found on disk (exit 1)
$SP scan --global-prefix "$(ruby -e 'print File.join(Gem.dir,"gems")')" --ecosystems gem --json # colorize found
Expected vs actual
- Expected:
-g scans "globally-installed packages" (CLI_CONTRACT.md, Global arguments). ruby_crawler.rs documents global mode as "queries gem env gemdir and gem env gempath", and gem_env_gems_dirs already contains Windows-specific ; splitting for that output, so Windows is meant to be supported. utils/process.rs documents that .cmd shims are found via PATHEXT (resolve_tool_with), but SystemCommandRunner doesn't use it.
- Actual: on RubyInstaller,
gem env never runs, and the global gem dir and XDG user dir are never scanned.
OS × version (probe run below)
| OS |
Ruby / RubyGems / Bundler |
scan -g finds colorize |
get -g |
--global-prefix <gemdir>/gems |
| windows-latest |
3.4.9 (x64-mingw-ucrt) / 3.6.9 / 4.0.22 |
no (scannedPackages: 0) |
fails (not found) |
finds it |
| windows-latest |
3.3.10 (x64-mingw-ucrt) / 3.5.22 / 4.0.22 |
no (scannedPackages: 0) |
fails (not found) |
finds it |
| windows-latest |
2.7.8 (x64-mingw32) / 3.1.6 / 2.4.22 |
only the ~/.gem user copy (scannedPackages: 1) |
"applied", but the system copy stays unpatched |
finds it |
| ubuntu-latest / macos-latest |
2.7.8, 3.3.10, 3.4.9 |
yes (both copies) |
patches both copies |
finds it |
An earlier run of the same probe (https://github.com/SocketDev/socket-patch/actions/runs/36815758908, whose mock API failed to start) also showed the Windows 3.3 / 3.4 jobs discovering no global gems.
First bad version
This isn't a v5 regression. v4.0.0 and v3.3.0 spawn gem the same way (SystemCommandRunner.run("gem", &["env", key]) / runner.run("gem", …); checked in the source only).
Suspect code
crates/socket-patch-core/src/crawlers/ruby_crawler.rs:547-553 (run_gem_env) → crates/socket-patch-core/src/utils/process.rs:137-138 (SystemCommandRunner::run → Command::new(bin) with no PATHEXT resolution). resolve_tool_with in the same file already handles .cmd / .bat.
crates/socket-patch-core/src/crawlers/ruby_crawler.rs:461- (get_global_gem_paths): the fallback list has no RubyInstaller location and no ~/.local/share/gem/ruby (XDG) user dir.
Probe run: https://github.com/SocketDev/socket-patch/actions/runs/36816092864
[agent] Found by the scheduled Bundler (RubyGems) bug-hunt routine (ledger #316).
Summary
The ruby crawler finds the global gem homes by running
gem env gemdirandgem env gempaththroughSystemCommandRunner.run("gem", …), which isstd::process::Command::new("gem"). On Windows,Command::newresolves onlygem.exeonPATH. RubyInstaller shipsgem.cmdplus an extensionlessgemscript and nogem.exe, so the spawn fails, both answers come backNone, and the crawler falls back to its hard-coded list (~/.gem/ruby/*,~/.rbenv,~/.rvm,/usr/lib/ruby/gems, …). None of those cover a RubyInstaller gem dir (C:\Ruby3x-x64\lib\ruby\gems\3.x.0, orD:\a\_temp\rubyinstaller-…in CI) or the RubyGems ≥ 3.5 user dir (~/.local/share/gem/ruby/3.x.0).As a result:
scan -gexits 0 and reportsscannedPackages: 0, so global gems with patches are silently missing from the report.get -g <uuid>fails withThe targeted manifest patch matched no installed package: pkg:gem/colorize@0.8.1, even though the gem is installed globally.vex -gomits the purl (package_not_found).~/.gem/ruby/2.7.0, which the fallback list happens to cover),-gsees only the user-install copy.get -greports success while the system copy in the RubyInstaller gem dir stays unpatched (Using ruby gem paths at: C:\Users\runneradmin\.gem\ruby\2.7.0\gems).--global-prefix <gemdir>\gemsworks on the same runners (the copy is found), which confirms that discovery is the broken step and not the patching.Impact
Global Windows gem installs are invisible to the documented
-gflow on current RubyInstaller Rubies, andscan -ggives no hint (exit 0, empty result). The samegem envlookup feeds local mode's non-deployment fallback (abundle installwithoutBUNDLE_PATHinstalls into the gem dir), so Windows Bundler projects on system gems are probably affected too. I haven't verified that separately.Repro (windows-latest,
ruby/setup-ruby, Git Bash; a mock patch API on 127.0.0.1 serves one patch forcolorize@0.8.1)Expected vs actual
-gscans "globally-installed packages" (CLI_CONTRACT.md, Global arguments).ruby_crawler.rsdocuments global mode as "queriesgem env gemdirandgem env gempath", andgem_env_gems_dirsalready contains Windows-specific;splitting for that output, so Windows is meant to be supported.utils/process.rsdocuments that.cmdshims are found viaPATHEXT(resolve_tool_with), butSystemCommandRunnerdoesn't use it.gem envnever runs, and the global gem dir and XDG user dir are never scanned.OS × version (probe run below)
scan -gfinds colorizeget -g--global-prefix <gemdir>/gemsscannedPackages: 0)scannedPackages: 0)~/.gemuser copy (scannedPackages: 1)An earlier run of the same probe (https://github.com/SocketDev/socket-patch/actions/runs/36815758908, whose mock API failed to start) also showed the Windows 3.3 / 3.4 jobs discovering no global gems.
First bad version
This isn't a v5 regression. v4.0.0 and v3.3.0 spawn
gemthe same way (SystemCommandRunner.run("gem", &["env", key])/runner.run("gem", …); checked in the source only).Suspect code
crates/socket-patch-core/src/crawlers/ruby_crawler.rs:547-553(run_gem_env) →crates/socket-patch-core/src/utils/process.rs:137-138(SystemCommandRunner::run→Command::new(bin)with noPATHEXTresolution).resolve_tool_within the same file already handles.cmd/.bat.crates/socket-patch-core/src/crawlers/ruby_crawler.rs:461-(get_global_gem_paths): the fallback list has no RubyInstaller location and no~/.local/share/gem/ruby(XDG) user dir.Probe run: https://github.com/SocketDev/socket-patch/actions/runs/36816092864