Skip to content

Commit d0323dd

Browse files
authored
Fix msbuild parser allowing missing versions (#1559)
This change updates the `msbuild` lockfile parser so that it will not allow for missing names and or versions. Before this change, a `*.csproj` file parsed as a lockfile (e.g., with type of `msbuild`) would show entries with missing name or version as an empty string. This causes analysis failures when submitting to the API since a valid package descriptor requires a non-empty `version` field. Dependency management in NuGet's "Central Package Management" (CPM) allows for `*.csproj` files containing `PackageReference` elements without a `Version` attribute. Those versions will be included, along with the fully transitive set, in the `packages.lock.json` lockfile generated by NuGet. When both files are present in the same directory, the changes in this patch will correctly parse both. For more about CPM, see this reference: https://devblogs.microsoft.com/nuget/introducing-central-package-management/ The `sample.csproj` test fixture was updated to include an entry with neither a name or version and another entry with a name but no version.
1 parent 007b856 commit d0323dd

File tree

3 files changed

+21
-9
lines changed

3 files changed

+21
-9
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1212

1313
- `phylum exception` subcommand for managing suppressions
1414

15+
### Fixed
16+
17+
- `msbuild` lockfile parser allowing missing names and versions
18+
1519
## 7.2.0 - 2024-12-10
1620

1721
### Added

lockfile/src/csharp.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ pub struct CSProj;
9595
#[derive(Debug, Deserialize, PartialEq, Eq)]
9696
pub struct PackageReference {
9797
#[serde(alias = "@Include", default)]
98-
pub name: String,
98+
pub name: Option<String>,
9999

100100
#[serde(alias = "@Version", alias = "@version", alias = "Version", default)]
101-
pub version: String,
101+
pub version: Option<String>,
102102
}
103103

104104
#[derive(Debug, Deserialize, PartialEq, Eq)]
@@ -113,13 +113,15 @@ struct Project {
113113
pub item_groups: Vec<ItemGroup>,
114114
}
115115

116-
impl From<PackageReference> for Package {
117-
fn from(pkg_ref: PackageReference) -> Self {
118-
Self {
119-
name: pkg_ref.name,
120-
version: PackageVersion::FirstParty(pkg_ref.version),
116+
impl TryFrom<PackageReference> for Package {
117+
type Error = ();
118+
119+
fn try_from(pkg_ref: PackageReference) -> Result<Self, Self::Error> {
120+
Ok(Self {
121+
name: pkg_ref.name.ok_or(())?,
122+
version: PackageVersion::FirstParty(pkg_ref.version.ok_or(())?),
121123
package_type: PackageType::Nuget,
122-
}
124+
})
123125
}
124126
}
125127

@@ -130,7 +132,11 @@ impl From<Project> for Vec<Package> {
130132
for item_group in proj.item_groups {
131133
if !item_group.dependencies.is_empty() {
132134
deps.extend(
133-
item_group.dependencies.into_iter().map(Package::from).collect::<Vec<_>>(),
135+
item_group
136+
.dependencies
137+
.into_iter()
138+
.filter_map(|pkg| Package::try_from(pkg).ok())
139+
.collect::<Vec<_>>(),
134140
);
135141
}
136142
}

tests/fixtures/sample.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13+
<PackageReference />
1314
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" />
1415
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
1516
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
@@ -20,6 +21,7 @@
2021
<PackageReference Include="System.Collections.Immutable">
2122
<version>1.5.0</version>
2223
</PackageReference>
24+
<PackageReference Include="Newtonsoft.Json"/>
2325
</ItemGroup>
2426

2527
<ItemGroup>

0 commit comments

Comments
 (0)