Skip to content

Commit

Permalink
Ignore platform-specific gems (#1543)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
cd-work authored Nov 26, 2024
1 parent 7c5ea30 commit 538113f
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed

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

## 7.1.4 - 2024-11-07

Expand Down
8 changes: 4 additions & 4 deletions lockfile/src/parsers/gem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ use crate::{Package, PackageVersion, ThirdPartyVersion};
const DEFAULT_REGISTRY: &str = "https://rubygems.org/";

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

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

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

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

/// Parser allowing only strict `1.2.3-alpha+build3` versions.
/// Parser allowing only strict `1.2.3.alpha.1` versions.
fn strict_package_version(input: &str) -> IResult<&str, &str> {
let (input, _) = space0(input)?;
recognize(many1(satisfy(|c: char| {
Expand Down
22 changes: 19 additions & 3 deletions lockfile/src/ruby.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,17 @@ pub struct GemLock;
impl Parse for GemLock {
/// Parses `Gemfile.lock` files into a vec of packages
fn parse(&self, data: &str) -> anyhow::Result<Vec<Package>> {
let (_, entries) = gem::parse(data)
let (_, mut packages) = gem::parse(data)
.finish()
.map_err(|e| anyhow!(convert_error(data, e)))
.context("Failed to parse gem lockfile")?;
Ok(entries)

// Remove duplicate dependencies, which can occur when a dependency is included
// with multiple different platform suffixes.
packages.sort_unstable();
packages.dedup();

Ok(packages)
}

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

let expected_pkgs = [
Package {
Expand Down Expand Up @@ -84,6 +90,16 @@ mod tests {
}),
package_type: PackageType::RubyGems,
},
Package {
name: "ffi".into(),
version: PackageVersion::FirstParty("1.17.0".into()),
package_type: PackageType::RubyGems,
},
Package {
name: "fake".into(),
version: PackageVersion::FirstParty("1.2.3".into()),
package_type: PackageType::RubyGems,
},
];

for expected_pkg in expected_pkgs {
Expand Down
5 changes: 4 additions & 1 deletion tests/fixtures/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ GEM
rspec-core (~> 3.11.0)
rspec-expectations (~> 3.11.0)
rspec-mocks (~> 3.11.0)
rspec-core (3.11.0-alpha+build3)
rspec-core (3.11.0)
rspec-support (~> 3.11.0)
rspec-expectations (3.11.1)
diff-lcs (>= 1.2.0, < 2.0)
Expand All @@ -48,6 +48,9 @@ GEM
remote: https://rubygems.org/
specs:
wirble (0.1.3)
ffi (1.17.0)
ffi (1.17.0-x86_64-linux-gnu)
fake (1.2.3-x86_64-linux-gnu)

DEPENDENCIES
benchmark!
Expand Down

0 comments on commit 538113f

Please sign in to comment.