Skip to content

Commit 538113f

Browse files
authored
Ignore platform-specific gems (#1543)
This fixes an issue in the Ruby `Gemfile.lock` parser where version-specific dependencies like `ffi (1.17.0-x86_64-linux-gnu)` would cause the parser to crash. Since new Ruby Gems are not allowed to contain dashes, this patch simply discards Gems that contain a `-` in their version. There are technically two versions of `asciidoctor-reducer` (`1.0.0-rc.1` and `1.0.0-beta.1`) which contain dashes, but those are neither commonly used, nor a security risk. Closes #1540.
1 parent 7c5ea30 commit 538113f

File tree

4 files changed

+28
-8
lines changed

4 files changed

+28
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1111
### Fixed
1212

1313
- `pnpm` version 5 parser including metadata in package versions
14+
- Platform-specific dependencies ignored by the `Gemfile.lock` parser
1415

1516
## 7.1.4 - 2024-11-07
1617

lockfile/src/parsers/gem.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ use crate::{Package, PackageVersion, ThirdPartyVersion};
1515
const DEFAULT_REGISTRY: &str = "https://rubygems.org/";
1616

1717
/// Legal non-alphanumeric characters in loose version specifications.
18-
const LOOSE_VERSION_CHARS: &[char] = &[' ', ',', '<', '>', '=', '~', '!', '.', '-', '+'];
18+
const LOOSE_VERSION_CHARS: &[char] = &[' ', ',', '<', '>', '=', '~', '!', '.', '-', '+', '_'];
1919

2020
/// Legal non-alphanumeric characters in strict version specifications.
21-
const STRICT_VERSION_CHARS: &[char] = &['.', '-', '+'];
21+
const STRICT_VERSION_CHARS: &[char] = &['.'];
2222

2323
#[derive(Debug)]
2424
struct Section<'a> {
@@ -224,7 +224,7 @@ fn package_name(input: &str) -> IResult<&str, &str> {
224224
}
225225

226226
/// Parser allowing for loose `(>= 1.2.0, < 2.0, != 1.2.3)` and strict
227-
/// `(1.2.3-alpha+build3)` versions.
227+
/// `(1.2.3.alpha.1)` versions.
228228
fn loose_package_version(input: &str) -> IResult<&str, &str> {
229229
// Versions can be completely omitted for sub-dependencies.
230230
if input.is_empty() {
@@ -241,7 +241,7 @@ fn loose_package_version(input: &str) -> IResult<&str, &str> {
241241
)(input)
242242
}
243243

244-
/// Parser allowing only strict `1.2.3-alpha+build3` versions.
244+
/// Parser allowing only strict `1.2.3.alpha.1` versions.
245245
fn strict_package_version(input: &str) -> IResult<&str, &str> {
246246
let (input, _) = space0(input)?;
247247
recognize(many1(satisfy(|c: char| {

lockfile/src/ruby.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,17 @@ pub struct GemLock;
1717
impl Parse for GemLock {
1818
/// Parses `Gemfile.lock` files into a vec of packages
1919
fn parse(&self, data: &str) -> anyhow::Result<Vec<Package>> {
20-
let (_, entries) = gem::parse(data)
20+
let (_, mut packages) = gem::parse(data)
2121
.finish()
2222
.map_err(|e| anyhow!(convert_error(data, e)))
2323
.context("Failed to parse gem lockfile")?;
24-
Ok(entries)
24+
25+
// Remove duplicate dependencies, which can occur when a dependency is included
26+
// with multiple different platform suffixes.
27+
packages.sort_unstable();
28+
packages.dedup();
29+
30+
Ok(packages)
2531
}
2632

2733
fn is_path_lockfile(&self, path: &Path) -> bool {
@@ -48,7 +54,7 @@ mod tests {
4854
#[test]
4955
fn lock_parse_gem() {
5056
let pkgs = GemLock.parse(include_str!("../../tests/fixtures/Gemfile.lock")).unwrap();
51-
assert_eq!(pkgs.len(), 11);
57+
assert_eq!(pkgs.len(), 13);
5258

5359
let expected_pkgs = [
5460
Package {
@@ -84,6 +90,16 @@ mod tests {
8490
}),
8591
package_type: PackageType::RubyGems,
8692
},
93+
Package {
94+
name: "ffi".into(),
95+
version: PackageVersion::FirstParty("1.17.0".into()),
96+
package_type: PackageType::RubyGems,
97+
},
98+
Package {
99+
name: "fake".into(),
100+
version: PackageVersion::FirstParty("1.2.3".into()),
101+
package_type: PackageType::RubyGems,
102+
},
87103
];
88104

89105
for expected_pkg in expected_pkgs {

tests/fixtures/Gemfile.lock

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ GEM
3131
rspec-core (~> 3.11.0)
3232
rspec-expectations (~> 3.11.0)
3333
rspec-mocks (~> 3.11.0)
34-
rspec-core (3.11.0-alpha+build3)
34+
rspec-core (3.11.0)
3535
rspec-support (~> 3.11.0)
3636
rspec-expectations (3.11.1)
3737
diff-lcs (>= 1.2.0, < 2.0)
@@ -48,6 +48,9 @@ GEM
4848
remote: https://rubygems.org/
4949
specs:
5050
wirble (0.1.3)
51+
ffi (1.17.0)
52+
ffi (1.17.0-x86_64-linux-gnu)
53+
fake (1.2.3-x86_64-linux-gnu)
5154

5255
DEPENDENCIES
5356
benchmark!

0 commit comments

Comments
 (0)