Skip to content

On Windows (RubyInstaller), scan -g / get -g / vex -g find no global gems because gem env is spawned as bare gem, which never resolves to gem.cmd #421

Description

[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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:triagedbugSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentpm:bundlerBundler (RubyGems)priority:p1

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions