Repository navigation
VEX gemspec product detection reads commented-out # spec.name = / # spec.version = lines, so the document names the wrong product or version #1573
Description
[agent] Found by the scheduled Bundler (RubyGems) bug-hunt routine (ledger #316).
Summary
vex (and scan/apply/vendor --vex without --vex-product) names the top-level product of a gem library project from its root *.gemspec (parse_gemspec, probe 9). The parser takes the first line whose =-left side ends in .name / .version and whose right side starts with a quote. It never skips Ruby comments, so a commented-out assignment wins over the live one:
# spec.version = "0.0.1"abovespec.version = Acme::VERSION→ productpkg:gem/acme@0.0.1(the real version is 2.3.4; a computed version should be dropped, givingpkg:gem/acme).# spec.name = "acme-legacy"abovespec.name = "acme"→ productpkg:gem/acme-legacy.
No warning is printed. Ruby (Gem::Specification.load) gives acme-2.3.4 for both files.
Impact
The OpenVEX document's products[].@id names a product or version that doesn't exist, so consumers that match VEX statements to their SBOM by product purl won't apply them (or will apply them to the wrong release). The run reports success. Leaving old assignments commented out is a common edit when a gem moves its version into a VERSION constant, or after a gem is renamed.
Repro (Linux, Ruby 3.3.6, Bundler 2.5.22 / 4.0.18; main e76cb9b)
mkdir -p acme/lib/acme && cd acme
echo 'module Acme; VERSION = "2.3.4"; end' > lib/acme/version.rb
cat > acme.gemspec <<'E'
require_relative "lib/acme/version"
Gem::Specification.new do |spec|
spec.name = "acme"
# spec.version = "0.0.1" # pinned before the VERSION constant existed
spec.version = Acme::VERSION
spec.authors = ["x"]
spec.summary = "x"
spec.files = []
spec.add_dependency "colorize", "0.8.1"
end
E
printf 'source "https://rubygems.org"\ngemspec\n' > Gemfile
bundle install
# any applied gem patch in .socket/manifest.json (hand-written colorize@0.8.1 manifest + `apply --offline` here)
socket-patch apply --offline
socket-patch vex | grep '"@id": "pkg:gem/acme'
# "@id": "pkg:gem/acme@0.0.1"
ruby -e 'puts Gem::Specification.load("acme.gemspec").full_name'
# acme-2.3.4The name variant: put # spec.name = "acme-legacy" above Gem::Specification.new (and drop the commented version). vex then gives "@id": "pkg:gem/acme-legacy". Each shape reproduced twice.
Expected vs actual
- Expected:
parse_gemspec's own doc says the product comes "from literal<spec>.name = "…"/<spec>.version = "…"assignments; a version computed from a constant (Foo::VERSION) is dropped" (crates/socket-patch-core/src/vex/product.rs:363-366). A comment is not an assignment, so this file should givepkg:gem/acme(version dropped).vex.rs:66documents probe 9 aspkg:gem/<name>[@<version>]. - Actual:
pkg:gem/acme@0.0.1/pkg:gem/acme-legacy.
Matrix
| OS | Ruby / Bundler | Commented version |
Commented name |
|---|---|---|---|
| Linux (sandbox) | 3.3.6 / 2.5.22 | reproduces (×2) | reproduces (×2) |
The parser is OS- and Bundler-independent (pure text), so macOS / Windows aren't probed.
Suspect code
crates/socket-patch-core/src/vex/product.rs:367-380: the literal closure trims the line and checks lhs.ends_with(".name") without first dropping lines that start with # (or text after a # outside a string). =begin/=end blocks and heredocs are also read as code, though those are rarer.
First bad version: not bisected (the sandbox clone is shallow). parse_gemspec has had this shape since gemspec detection was added.
Activity
mikolalysenko commentedon Oct 15, 2026
[agent] Triaged: priority:p1 (RubyGems/Bundler). Confirmed on main
e76cb9bby readingparse_gemspec(crates/socket-patch-core/src/vex/product.rs:367-381): theliteralclosure splits each trimmed line on the first=and only checks that the left side ends with.name/.version, so# spec.version = "0.0.1"matches (left side# spec.version) before the livespec.version = Acme::VERSIONline. No duplicate or existing fix PR found. Not clustered: no other open issue shares this parser.Generated by Claude Code
mikolalysenko commentedon Oct 15, 2026
[agent] Claiming this issue (single-issue cluster; root cause:
parse_gemspecreads Ruby comments as assignments). Branch: agent/fix-gemspec-comment-parse. Claim-ID: 2026-10-15T16:20:57Z-e577a2Generated by Claude Code
mikolalysenko commentedon Oct 15, 2026
[agent] Fix in progress: #1582
Generated by Claude Code
Skip Ruby comments when naming a gem VEX product