diff --git a/syft/pkg/cataloger/dotnet/cataloger_test.go b/syft/pkg/cataloger/dotnet/cataloger_test.go index 1e135318d..8b333bc8b 100644 --- a/syft/pkg/cataloger/dotnet/cataloger_test.go +++ b/syft/pkg/cataloger/dotnet/cataloger_test.go @@ -489,6 +489,40 @@ func TestCataloger(t *testing.T) { "netstandard @ 8.0.1425.11118 (/app/netstandard.dll)", ) + assertAllDepEntriesInEmbeddedExecutable := func(t *testing.T, pkgs []pkg.Package, relationships []artifact.Relationship) { + t.Helper() + for _, p := range pkgs { + // assert that all packages DO NOT have an executable associated with it + m, ok := p.Metadata.(pkg.DotnetDepsEntry) + if !ok { + t.Fatalf("expected metadata to be of type DotnetDepsEntry") + } + if len(m.Executables) != 0 { + t.Errorf("expected no executables for package %s, found %d", p.Name, len(m.Executables)) + } + } + + actual := extractMatchingPackage(t, "Newtonsoft.Json", pkgs) + expected := pkg.Package{ + Name: "Newtonsoft.Json", + Version: "13.0.3", + Locations: file.NewLocationSet(file.NewLocation("/app/dotnetapp.exe")), // important! not this is an exe + Language: pkg.Dotnet, + Type: pkg.DotnetPkg, + PURL: "pkg:nuget/Newtonsoft.Json@13.0.3", + Metadata: pkg.DotnetDepsEntry{ + Name: "Newtonsoft.Json", + Version: "13.0.3", + Path: "newtonsoft.json/13.0.3", + Sha512: "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", + HashPath: "newtonsoft.json.13.0.3.nupkg.sha512", + Executables: nil, // important! + }, + } + + pkgtest.AssertPackagesEqualIgnoreLayers(t, expected, actual) + } + assertAllDepEntriesWithoutExecutables := func(t *testing.T, pkgs []pkg.Package, relationships []artifact.Relationship) { t.Helper() for _, p := range pkgs { @@ -895,12 +929,163 @@ func TestCataloger(t *testing.T) { name: "combined cataloger (single file)", fixture: "image-net8-app-single-file", cataloger: NewDotnetDepsBinaryCataloger(DefaultCatalogerConfig()), - - // important: no relationships should be found - expectedPkgs: []string{ - "dotnetapp @ 1.0.0.0 (/app/dotnetapp.exe)", + expectedPkgs: []string{"Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + // extracted libraries from the embedded deps.json + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.af @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.ar @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.az @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.bg @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.bn-BD @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.cs @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.da @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.de @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.el @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.es @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.fa @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.fi-FI @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.fr @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.fr-BE @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.he @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.hr @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.hu @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.hy @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.id @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.is @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.it @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.ja @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.ko-KR @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.ku @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.lv @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.ms-MY @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.mt @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.nb @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.nb-NO @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.nl @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.pl @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.pt @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.ro @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.ru @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.sk @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.sl @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.sr @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.sr-Latn @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.sv @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.th-TH @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.tr @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.uk @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.uz-Cyrl-UZ @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.uz-Latn-UZ @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.vi @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.zh-CN @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.zh-Hans @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.zh-Hant @ 2.14.1 (/app/dotnetapp.exe)", + "Newtonsoft.Json @ 13.0.3 (/app/dotnetapp.exe)", + "dotnetapp @ 1.0.0 (/app/dotnetapp.exe)", + "runtimepack.Microsoft.NETCore.App.Runtime.win-x64 @ 8.0.14 (/app/dotnetapp.exe)", }, - assertion: assertSingleFileDeployment, + expectedRels: []string{ + "Humanizer @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] dotnetapp @ 1.0.0 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.af @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.ar @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.az @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.bg @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.bn-BD @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.cs @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.da @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.de @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.el @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.es @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.fa @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.fi-FI @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.fr @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.fr-BE @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.he @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.hr @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.hu @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.hy @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.id @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.is @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.it @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.ja @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.ko-KR @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.ku @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.lv @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.ms-MY @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.mt @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.nb @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.nb-NO @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.nl @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.pl @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.pt @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.ro @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.ru @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.sk @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.sl @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.sr @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.sr-Latn @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.sv @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.th-TH @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.tr @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.uk @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.uz-Cyrl-UZ @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.uz-Latn-UZ @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.vi @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.zh-CN @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.zh-Hans @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer.Core.zh-Hant @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.af @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.ar @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.az @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.bg @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.bn-BD @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.cs @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.da @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.de @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.el @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.es @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.fa @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.fi-FI @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.fr @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.fr-BE @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.he @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.hr @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.hu @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.hy @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.id @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.is @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.it @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.ja @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.ko-KR @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.ku @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.lv @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.ms-MY @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.mt @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.nb @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.nb-NO @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.nl @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.pl @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.pt @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.ro @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.ru @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.sk @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.sl @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.sr @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.sr-Latn @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.sv @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.th-TH @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.tr @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.uk @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.uz-Cyrl-UZ @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.uz-Latn-UZ @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.vi @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.zh-CN @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.zh-Hans @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Humanizer.Core.zh-Hant @ 2.14.1 (/app/dotnetapp.exe) [dependency-of] Humanizer @ 2.14.1 (/app/dotnetapp.exe)", + "Newtonsoft.Json @ 13.0.3 (/app/dotnetapp.exe) [dependency-of] dotnetapp @ 1.0.0 (/app/dotnetapp.exe)", + "runtimepack.Microsoft.NETCore.App.Runtime.win-x64 @ 8.0.14 (/app/dotnetapp.exe) [dependency-of] dotnetapp @ 1.0.0 (/app/dotnetapp.exe)", + }, + assertion: assertAllDepEntriesInEmbeddedExecutable, }, { name: "pe cataloger (single file)", diff --git a/syft/pkg/cataloger/dotnet/deps_binary_cataloger.go b/syft/pkg/cataloger/dotnet/deps_binary_cataloger.go index 475800b6e..b26be3cfd 100644 --- a/syft/pkg/cataloger/dotnet/deps_binary_cataloger.go +++ b/syft/pkg/cataloger/dotnet/deps_binary_cataloger.go @@ -3,6 +3,7 @@ package dotnet import ( "context" "fmt" + "io" "path" "regexp" "sort" @@ -147,6 +148,18 @@ func isRuntimePackageLocation(loc file.Location) (string, bool) { // partitionPEs pairs PE files with the deps.json based on directory containment. func partitionPEs(depJsons []logicalDepsJSON, peFiles []logicalPE) ([]logicalDepsJSON, []logicalPE, []logicalDepsJSON) { + // if there are any embedded deps.json files in PE files, extract them and add them to the list of deps.json files to process. + consideredPEs := file.NewCoordinateSet() + for _, pe := range peFiles { + if pe.EmbeddedDepsJSON != "" { + dep := extractEmbeddedDeps(pe) + if dep != nil { + depJsons = append(depJsons, *dep) + consideredPEs.Add(pe.Location.Coordinates) // mark this PE as already considered + } + } + } + // sort deps.json paths from longest to shortest. This is so we are processing the most specific match first. sort.Slice(depJsons, func(i, j int) bool { return depJsons[i].Location.RealPath > depJsons[j].Location.RealPath @@ -170,7 +183,9 @@ func partitionPEs(depJsons []logicalDepsJSON, peFiles []logicalPE) ([]logicalDep // across multiple deps.json files. } } - if !found { + // if we did not find a deps.json to associate this PE with, keep track of it for later processing. + // also, if we have already considered this PE because it had an embedded deps.json, skip it. + if !found && !consideredPEs.Contains(pe.Location.Coordinates) { remainingPeFiles = append(remainingPeFiles, pe) } } @@ -489,3 +504,14 @@ func readPEFile(resolver file.Resolver, loc file.Location) (*logicalPE, error) { return ldpe, nil } + +func extractEmbeddedDeps(pe logicalPE) *logicalDepsJSON { + doc, err := newDepsJSON(file.NewLocationReadCloser(pe.Location, io.NopCloser(strings.NewReader(pe.EmbeddedDepsJSON)))) + if err != nil || doc == nil { + return nil + } + + doc.Location = pe.Location + lDoc := getLogicalDepsJSON(*doc, nil) + return &lDoc +} diff --git a/syft/pkg/cataloger/internal/pe/bundle.go b/syft/pkg/cataloger/internal/pe/bundle.go new file mode 100644 index 000000000..2fefc0acb --- /dev/null +++ b/syft/pkg/cataloger/internal/pe/bundle.go @@ -0,0 +1,259 @@ +package pe + +import ( + "bytes" + "debug/pe" + "encoding/binary" + "errors" + "fmt" + "io" +) + +// dotNetBundleSignature is the SHA-256 hash of ".net core bundle" used to identify single-file bundles. +var dotNetBundleSignature = []byte{ + 0x8b, 0x12, 0x02, 0xb9, 0x6a, 0x61, 0x20, 0x38, + 0x72, 0x7b, 0x93, 0x02, 0x14, 0xd7, 0xa0, 0x32, + 0x13, 0xf5, 0xb9, 0xe6, 0xef, 0xae, 0x33, 0x18, + 0xee, 0x3b, 0x2d, 0xce, 0x24, 0xb3, 0x6a, 0xae, +} + +// dotNetBundleHeader represents the fixed portion of the bundle header (version 1+) +type dotNetBundleHeader struct { + MajorVersion uint32 + MinorVersion uint32 + NumEmbeddedFiles int32 +} + +// dotNetBundleHeaderV2 represents additional fields in V2+ bundles (.NET 5+) +type dotNetBundleHeaderV2 struct { + DepsJSONOffset int64 + DepsJSONSize int64 + RuntimeConfigJSONOffset int64 + RuntimeConfigJSONSize int64 + Flags uint64 +} + +// dotNetFileType represents the type of bundled file in the manifest +type dotNetFileType uint8 + +const ( + dotNetFileTypeUnknown dotNetFileType = iota + dotNetFileTypeAssembly + dotNetFileTypeNativeBinary + dotNetFileTypeDepsJSON + dotNetFileTypeRuntimeConfigJSON + dotNetFileTypeSymbols +) + +// extractDepsJSONFromBundle searches for an embedded deps.json file in a .NET single-file bundle. +// When built with PublishSingleFile=true, .NET embeds the application and all dependencies into +// the AppHost executable. The bundle marker (8-byte header offset + 32-byte signature) is placed +// in a placeholder location within the PE structure, pointing to the bundle header which contains +// file entry metadata. For V2+ bundles (.NET 5+), the header includes direct offsets to deps.json; +// for V1 bundles (.NET Core 3.x), we parse the manifest to locate it. +// +// ┌──────────────────────────────────┐ +// │ PE AppHost Binary │ Standard PE structure +// │ ... │ +// │ [8B offset][32B signature] │ Bundle marker (in placeholder within PE) +// │ ... │ +// ├──────────────────────────────────┤ +// │ Bundled Files │ Raw file contents (assemblies, deps.json, etc.) +// ├──────────────────────────────────┤ +// │ Bundle Header │ Version info, file count, deps.json offset (V2+) +// │ File Manifest │ Per-file: offset, size, type, path +// └──────────────────────────────────┘ +// +// Parsing strategy: +// 1. Search only the PE portion (using section headers) for the bundle signature +// 2. Read 8 bytes before signature to get header offset +// 3. Parse header to get deps.json location (V2+) or scan manifest entries (V1) +// +// See related documentation for more information: +// - https://github.com/dotnet/designs/blob/main/accepted/2020/single-file/design.md +// - https://github.com/dotnet/designs/blob/main/accepted/2020/single-file/bundler.md +// - https://github.com/dotnet/runtime/blob/main/src/installer/managed/Microsoft.NET.HostModel/Bundle/Manifest.cs +// - https://github.com/dotnet/runtime/blob/main/src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs +// - https://github.com/dotnet/runtime/blob/main/src/native/corehost/bundle/header.h +// - https://github.com/dotnet/runtime/blob/main/src/native/corehost/bundle/file_entry.h +// - https://github.com/dotnet/runtime/blob/main/src/native/corehost/bundle/file_type.h +func extractDepsJSONFromBundle(r io.ReadSeeker, sections []pe.SectionHeader32) (string, error) { + headerOffset, err := findBundleHeaderOffset(r, sections) + if err != nil { + return "", err + } + if headerOffset == 0 { + return "", nil // not a .NET single-file bundle + } + + return readDepsJSONFromBundleHeader(r, headerOffset) +} + +// findBundleHeaderOffset locates the bundle marker within the PE structure and returns the header offset. +// Returns 0 if no bundle marker is found (not a single-file bundle). +func findBundleHeaderOffset(r io.ReadSeeker, sections []pe.SectionHeader32) (int64, error) { + peEndOffset := calculatePEEndOffset(sections) + + if _, err := r.Seek(0, io.SeekStart); err != nil { + return 0, err + } + + peData := make([]byte, peEndOffset) + n, err := io.ReadFull(r, peData) + if err != nil && !errors.Is(err, io.ErrUnexpectedEOF) { + return 0, err + } + peData = peData[:n] + + idx := bytes.Index(peData, dotNetBundleSignature) + if idx == -1 || idx < 8 { + return 0, nil + } + + // the header offset is stored in the 8 bytes immediately before the signature + headerOffset := int64(binary.LittleEndian.Uint64(peData[idx-8 : idx])) + return headerOffset, nil +} + +// calculatePEEndOffset determines where the PE structure ends based on section headers, +// adding padding for alignment. This bounds our search for the bundle marker. +func calculatePEEndOffset(sections []pe.SectionHeader32) int64 { + var peEndOffset int64 + for _, sec := range sections { + endOfSection := int64(sec.PointerToRawData) + int64(sec.SizeOfRawData) + if endOfSection > peEndOffset { + peEndOffset = endOfSection + } + } + // add buffer for alignment padding after sections + return peEndOffset + 4096 +} + +// readDepsJSONFromBundleHeader parses the bundle header at the given offset and extracts deps.json content. +func readDepsJSONFromBundleHeader(r io.ReadSeeker, headerOffset int64) (string, error) { + if _, err := r.Seek(headerOffset, io.SeekStart); err != nil { + return "", err + } + + var header dotNetBundleHeader + if err := binary.Read(r, binary.LittleEndian, &header); err != nil { + return "", err + } + + // skip bundle ID (7-bit length-prefixed string) + if err := skipDotNetString(r); err != nil { + return "", err + } + + // for V2+ bundles (.NET 5+), read deps.json location directly from header + if header.MajorVersion >= 2 { + var headerV2 dotNetBundleHeaderV2 + if err := binary.Read(r, binary.LittleEndian, &headerV2); err != nil { + return "", err + } + + if headerV2.DepsJSONSize > 0 && headerV2.DepsJSONOffset > 0 { + return readDepsJSONAtOffset(r, headerV2.DepsJSONOffset, headerV2.DepsJSONSize) + } + } + + // for V1 bundles (.NET Core 3.x) or if V2 header doesn't have deps.json, parse manifest + return findDepsJSONInManifest(r, header.NumEmbeddedFiles, header.MajorVersion) +} + +// skipDotNetString skips a 7-bit length-prefixed string (.NET BinaryWriter format) +func skipDotNetString(r io.ReadSeeker) error { + length, err := read7BitEncodedInt(r) + if err != nil { + return err + } + _, err = r.Seek(int64(length), io.SeekCurrent) + return err +} + +// read7BitEncodedInt reads a .NET 7-bit encoded integer (variable-length encoding used by BinaryWriter) +func read7BitEncodedInt(r io.Reader) (int, error) { + result := 0 + shift := 0 + for { + var b [1]byte + if _, err := r.Read(b[:]); err != nil { + return 0, err + } + result |= int(b[0]&0x7F) << shift + if b[0]&0x80 == 0 { + break + } + shift += 7 + if shift >= 35 { // prevent overflow + return 0, errors.New("invalid 7-bit encoded int") + } + } + return result, nil +} + +// readDepsJSONAtOffset reads deps.json content at a specific offset using seeks (avoiding loading entire file) +func readDepsJSONAtOffset(r io.ReadSeeker, offset, size int64) (string, error) { + if _, err := r.Seek(offset, io.SeekStart); err != nil { + return "", fmt.Errorf("failed to seek to deps.json at offset %d: %w", offset, err) + } + data := make([]byte, size) + if _, err := io.ReadFull(r, data); err != nil { + return "", fmt.Errorf("failed to read deps.json (%d bytes): %w", size, err) + } + return string(data), nil +} + +// findDepsJSONInManifest parses manifest entries to find deps.json (for V1 bundles or fallback) +func findDepsJSONInManifest(r io.ReadSeeker, numFiles int32, majorVersion uint32) (string, error) { + for i := int32(0); i < numFiles; i++ { + var offset, size int64 + + if err := binary.Read(r, binary.LittleEndian, &offset); err != nil { + return "", err + } + if err := binary.Read(r, binary.LittleEndian, &size); err != nil { + return "", err + } + + // V6+ bundles (.NET 6+) have compressed size field + if majorVersion >= 6 { + var compressedSize int64 + if err := binary.Read(r, binary.LittleEndian, &compressedSize); err != nil { + return "", err + } + } + + var fileType dotNetFileType + if err := binary.Read(r, binary.LittleEndian, &fileType); err != nil { + return "", err + } + + // skip relativePath string + if err := skipDotNetString(r); err != nil { + return "", err + } + + if fileType == dotNetFileTypeDepsJSON && size > 0 { + // save current position to resume manifest parsing if needed + currentPos, err := r.Seek(0, io.SeekCurrent) + if err != nil { + return "", err + } + + // read deps.json content + content, err := readDepsJSONAtOffset(r, offset, size) + if err != nil { + return "", err + } + + // restore position (in case caller needs to continue) + if _, err := r.Seek(currentPos, io.SeekStart); err != nil { + return "", err + } + + return content, nil + } + } + return "", nil +} diff --git a/syft/pkg/cataloger/internal/pe/bundle_test.go b/syft/pkg/cataloger/internal/pe/bundle_test.go new file mode 100644 index 000000000..d25b33f7c --- /dev/null +++ b/syft/pkg/cataloger/internal/pe/bundle_test.go @@ -0,0 +1,58 @@ +package pe + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_extractDepsJSONFromBundle_Versions(t *testing.T) { + tests := []struct { + name string + fixture string + path string + wantDepsJSON bool // true if deps.json should be found + wantJSONContain string // string that should be in the JSON (varies by .NET version) + }{ + { + name: "V1 bundle (.NET Core 3.1)", + fixture: "image-dotnet31-single-file", + path: "/app/hello.exe", + wantDepsJSON: true, + wantJSONContain: "runtimeOptions", // .NET Core 3.1 uses runtimeOptions + }, + { + name: "V2 bundle (.NET 5)", + fixture: "image-dotnet5-single-file", + path: "/app/hello.exe", + wantDepsJSON: true, + wantJSONContain: "runtimeTarget", // .NET 5+ uses runtimeTarget + }, + { + name: "V6 bundle (.NET 6)", + fixture: "image-dotnet6-single-file", + path: "/app/hello.exe", + wantDepsJSON: true, + wantJSONContain: "runtimeTarget", // .NET 6+ uses runtimeTarget + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + reader := fixtureFile(t, tt.fixture, tt.path) + defer reader.Close() + + got, err := Read(reader) + require.NoError(t, err) + + if tt.wantDepsJSON { + assert.NotEmpty(t, got.EmbeddedDepsJSON, "expected deps.json to be extracted from bundle") + // verify it looks like valid JSON for this .NET version + assert.Contains(t, got.EmbeddedDepsJSON, tt.wantJSONContain, "deps.json should contain expected field") + } else { + assert.Empty(t, got.EmbeddedDepsJSON, "expected no deps.json in non-bundle file") + } + }) + } +} diff --git a/syft/pkg/cataloger/internal/pe/pe.go b/syft/pkg/cataloger/internal/pe/pe.go index 395d607b5..d81923ffc 100644 --- a/syft/pkg/cataloger/internal/pe/pe.go +++ b/syft/pkg/cataloger/internal/pe/pe.go @@ -34,6 +34,10 @@ type File struct { // understand if this executable is even a .NET application. CLR *CLREvidence + // EmbeddedDepsJSON is the contents of an embedded deps.json file found within the PE file, if any. + // This is typical when using the PublishSingleFile build option. + EmbeddedDepsJSON string + // VersionResources is a map of version resource keys to their values found in the VERSIONINFO resource directory. VersionResources map[string]string } @@ -153,7 +157,7 @@ func Read(f file.LocationReadCloser) (*File, error) { return nil, err } - sections, _, err := parsePEFile(r) + sections, sectionHeaders, err := parsePEFile(r) if err != nil { return nil, fmt.Errorf("unable to parse PE sections: %w", err) } @@ -171,9 +175,15 @@ func Read(f file.LocationReadCloser) (*File, error) { return nil, fmt.Errorf("unable to parse PE CLR directory: %w", err) } + embeddedDepsJSON, err := extractDepsJSONFromBundle(r, sectionHeaders) + if err != nil { + return nil, fmt.Errorf("unable to extract embedded deps.json: %w", err) + } + return &File{ Location: f.Location, CLR: c, + EmbeddedDepsJSON: embeddedDepsJSON, VersionResources: versionResources, }, nil } diff --git a/syft/pkg/cataloger/internal/pe/pe_test.go b/syft/pkg/cataloger/internal/pe/pe_test.go index e95d33257..e04c1e00d 100644 --- a/syft/pkg/cataloger/internal/pe/pe_test.go +++ b/syft/pkg/cataloger/internal/pe/pe_test.go @@ -1,6 +1,8 @@ package pe import ( + "fmt" + "os" "testing" "github.com/google/go-cmp/cmp" @@ -14,13 +16,17 @@ import ( ) func Test_Read_DotNetDetection(t *testing.T) { + singleFileDepsJSON, err := os.ReadFile("test-fixtures/net8-app-single-file.deps.json") + require.NoError(t, err) + tests := []struct { - name string - fixture string - path string - wantVR map[string]string - wantCLR bool - wantErr require.ErrorAssertionFunc + name string + fixture string + path string + wantVR map[string]string + wantCLR bool + wantDepsJSON string + wantErr require.ErrorAssertionFunc }{ { name: "newtonsoft", @@ -114,7 +120,8 @@ func Test_Read_DotNetDetection(t *testing.T) { "ProductVersion": "1.0.0", "Assembly Version": "1.0.0.0", }, - wantErr: require.NoError, + wantDepsJSON: string(singleFileDepsJSON), + wantErr: require.NoError, }, } @@ -137,6 +144,11 @@ func Test_Read_DotNetDetection(t *testing.T) { } assert.Equal(t, tt.wantCLR, got.CLR.HasEvidenceOfCLR()) + + if d := cmp.Diff(tt.wantDepsJSON, got.EmbeddedDepsJSON); d != "" { + fmt.Printf("got embedded deps.json: %s\n", got.EmbeddedDepsJSON) + t.Errorf("unexpected deps.json location (-want +got): %s", d) + } }) } } diff --git a/syft/pkg/cataloger/internal/pe/test-fixtures/Makefile b/syft/pkg/cataloger/internal/pe/test-fixtures/Makefile new file mode 100644 index 000000000..44674c2c9 --- /dev/null +++ b/syft/pkg/cataloger/internal/pe/test-fixtures/Makefile @@ -0,0 +1,19 @@ +FINGERPRINT_FILE=cache.fingerprint + +.DEFAULT_GOAL := fixtures + +# requirement 1: 'fixtures' goal to generate any and all test fixtures +fixtures: + @echo "nothing to do" + +# requirement 2: 'fingerprint' goal to determine if cache should be busted +fingerprint: $(FINGERPRINT_FILE) + +# requirement 3: always recalculate fingerprint based on source +.PHONY: $(FINGERPRINT_FILE) +$(FINGERPRINT_FILE): + @find Makefile **/Dockerfile **/src/** -type f -exec sha256sum {} \; | sort -k2 > $(FINGERPRINT_FILE) + +# requirement 4: 'clean' goal to remove generated test fixtures +clean: + rm -f $(FINGERPRINT_FILE) diff --git a/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet31-single-file/Dockerfile b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet31-single-file/Dockerfile new file mode 100644 index 000000000..dc7f30763 --- /dev/null +++ b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet31-single-file/Dockerfile @@ -0,0 +1,11 @@ +FROM --platform=linux/amd64 mcr.microsoft.com/dotnet/core/sdk:3.1 AS build +WORKDIR /src +COPY src/ . +RUN dotnet publish -c Release -r win-x64 \ + -p:PublishSingleFile=true \ + -p:SelfContained=true \ + -o /app + +FROM busybox +WORKDIR /app +COPY --from=build /app/hello.exe . diff --git a/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet31-single-file/src/Program.cs b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet31-single-file/src/Program.cs new file mode 100644 index 000000000..d9a16e17d --- /dev/null +++ b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet31-single-file/src/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace Hello +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello"); + } + } +} diff --git a/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet31-single-file/src/hello.csproj b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet31-single-file/src/hello.csproj new file mode 100644 index 000000000..afa7bad5e --- /dev/null +++ b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet31-single-file/src/hello.csproj @@ -0,0 +1,6 @@ + + + Exe + netcoreapp3.1 + + diff --git a/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet5-single-file/Dockerfile b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet5-single-file/Dockerfile new file mode 100644 index 000000000..71ad584de --- /dev/null +++ b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet5-single-file/Dockerfile @@ -0,0 +1,11 @@ +FROM --platform=linux/amd64 mcr.microsoft.com/dotnet/sdk:5.0 AS build +WORKDIR /src +COPY src/ . +RUN dotnet publish -c Release -r win-x64 \ + -p:PublishSingleFile=true \ + -p:SelfContained=true \ + -o /app + +FROM busybox +WORKDIR /app +COPY --from=build /app/hello.exe . diff --git a/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet5-single-file/src/Program.cs b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet5-single-file/src/Program.cs new file mode 100644 index 000000000..e7b9629b1 --- /dev/null +++ b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet5-single-file/src/Program.cs @@ -0,0 +1 @@ +System.Console.WriteLine("Hello"); diff --git a/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet5-single-file/src/hello.csproj b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet5-single-file/src/hello.csproj new file mode 100644 index 000000000..dbc7a12ef --- /dev/null +++ b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet5-single-file/src/hello.csproj @@ -0,0 +1,6 @@ + + + Exe + net5.0 + + diff --git a/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet6-single-file/Dockerfile b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet6-single-file/Dockerfile new file mode 100644 index 000000000..2089ef9e6 --- /dev/null +++ b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet6-single-file/Dockerfile @@ -0,0 +1,11 @@ +FROM --platform=linux/amd64 mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY src/ . +RUN dotnet publish -c Release -r win-x64 \ + -p:PublishSingleFile=true \ + -p:SelfContained=true \ + -o /app + +FROM busybox +WORKDIR /app +COPY --from=build /app/hello.exe . diff --git a/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet6-single-file/src/Program.cs b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet6-single-file/src/Program.cs new file mode 100644 index 000000000..e7b9629b1 --- /dev/null +++ b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet6-single-file/src/Program.cs @@ -0,0 +1 @@ +System.Console.WriteLine("Hello"); diff --git a/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet6-single-file/src/hello.csproj b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet6-single-file/src/hello.csproj new file mode 100644 index 000000000..a69c6ed46 --- /dev/null +++ b/syft/pkg/cataloger/internal/pe/test-fixtures/image-dotnet6-single-file/src/hello.csproj @@ -0,0 +1,6 @@ + + + Exe + net6.0 + + diff --git a/syft/pkg/cataloger/internal/pe/test-fixtures/net8-app-single-file.deps.json b/syft/pkg/cataloger/internal/pe/test-fixtures/net8-app-single-file.deps.json new file mode 100644 index 000000000..191d24c6a --- /dev/null +++ b/syft/pkg/cataloger/internal/pe/test-fixtures/net8-app-single-file.deps.json @@ -0,0 +1,1622 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v8.0/win-x64", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v8.0": {}, + ".NETCoreApp,Version=v8.0/win-x64": { + "dotnetapp/1.0.0": { + "dependencies": { + "Humanizer": "2.14.1", + "Newtonsoft.Json": "13.0.3", + "runtimepack.Microsoft.NETCore.App.Runtime.win-x64": "8.0.14" + }, + "runtime": { + "dotnetapp.dll": {} + } + }, + "runtimepack.Microsoft.NETCore.App.Runtime.win-x64/8.0.14": { + "runtime": { + "Microsoft.CSharp.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "Microsoft.VisualBasic.Core.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.1425.11118" + }, + "Microsoft.VisualBasic.dll": { + "assemblyVersion": "10.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "Microsoft.Win32.Primitives.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "Microsoft.Win32.Registry.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.AppContext.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Buffers.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Collections.Concurrent.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Collections.Immutable.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Collections.NonGeneric.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Collections.Specialized.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Collections.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.ComponentModel.Annotations.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.ComponentModel.DataAnnotations.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.ComponentModel.EventBasedAsync.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.ComponentModel.Primitives.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.ComponentModel.TypeConverter.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.ComponentModel.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Configuration.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Console.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Core.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Data.Common.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Data.DataSetExtensions.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Data.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Diagnostics.Contracts.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Diagnostics.Debug.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Diagnostics.DiagnosticSource.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Diagnostics.FileVersionInfo.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Diagnostics.Process.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Diagnostics.StackTrace.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Diagnostics.TextWriterTraceListener.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Diagnostics.Tools.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Diagnostics.TraceSource.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Diagnostics.Tracing.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Drawing.Primitives.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Drawing.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Dynamic.Runtime.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Formats.Asn1.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Formats.Tar.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Globalization.Calendars.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Globalization.Extensions.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Globalization.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.Compression.Brotli.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.Compression.FileSystem.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.Compression.ZipFile.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.Compression.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.FileSystem.AccessControl.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.FileSystem.DriveInfo.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.FileSystem.Primitives.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.FileSystem.Watcher.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.FileSystem.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.IsolatedStorage.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.MemoryMappedFiles.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.Pipes.AccessControl.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.Pipes.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.UnmanagedMemoryStream.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.IO.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Linq.Expressions.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Linq.Parallel.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Linq.Queryable.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Linq.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Memory.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.Http.Json.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.Http.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.HttpListener.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.Mail.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.NameResolution.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.NetworkInformation.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.Ping.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.Primitives.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.Quic.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.Requests.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.Security.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.ServicePoint.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.Sockets.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.WebClient.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.WebHeaderCollection.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.WebProxy.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.WebSockets.Client.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.WebSockets.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Net.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Numerics.Vectors.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Numerics.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.ObjectModel.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Private.CoreLib.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Private.DataContractSerialization.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Private.Uri.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Private.Xml.Linq.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Private.Xml.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Reflection.DispatchProxy.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Reflection.Emit.ILGeneration.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Reflection.Emit.Lightweight.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Reflection.Emit.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Reflection.Extensions.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Reflection.Metadata.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Reflection.Primitives.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Reflection.TypeExtensions.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Reflection.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Resources.Reader.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Resources.ResourceManager.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Resources.Writer.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.CompilerServices.Unsafe.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.CompilerServices.VisualC.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.Extensions.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.Handles.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.InteropServices.JavaScript.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.InteropServices.RuntimeInformation.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.InteropServices.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.Intrinsics.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.Loader.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.Numerics.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.Serialization.Formatters.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.Serialization.Json.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.Serialization.Primitives.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.Serialization.Xml.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.Serialization.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Runtime.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Security.AccessControl.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Security.Claims.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Security.Cryptography.Algorithms.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Security.Cryptography.Cng.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Security.Cryptography.Csp.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Security.Cryptography.Encoding.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Security.Cryptography.OpenSsl.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Security.Cryptography.Primitives.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Security.Cryptography.X509Certificates.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Security.Cryptography.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Security.Principal.Windows.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Security.Principal.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Security.SecureString.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Security.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.ServiceModel.Web.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.ServiceProcess.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Text.Encoding.CodePages.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Text.Encoding.Extensions.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Text.Encoding.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Text.Encodings.Web.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Text.Json.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Text.RegularExpressions.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Threading.Channels.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Threading.Overlapped.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Threading.Tasks.Dataflow.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Threading.Tasks.Extensions.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Threading.Tasks.Parallel.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Threading.Tasks.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Threading.Thread.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Threading.ThreadPool.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Threading.Timer.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Threading.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Transactions.Local.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Transactions.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.ValueTuple.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Web.HttpUtility.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Web.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Windows.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Xml.Linq.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Xml.ReaderWriter.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Xml.Serialization.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Xml.XDocument.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Xml.XPath.XDocument.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Xml.XPath.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Xml.XmlDocument.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Xml.XmlSerializer.dll": { + "assemblyVersion": "8.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.Xml.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "System.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "WindowsBase.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "mscorlib.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "8.0.1425.11118" + }, + "netstandard.dll": { + "assemblyVersion": "2.1.0.0", + "fileVersion": "8.0.1425.11118" + } + } + }, + "Humanizer/2.14.1": { + "dependencies": { + "Humanizer.Core.af": "2.14.1", + "Humanizer.Core.ar": "2.14.1", + "Humanizer.Core.az": "2.14.1", + "Humanizer.Core.bg": "2.14.1", + "Humanizer.Core.bn-BD": "2.14.1", + "Humanizer.Core.cs": "2.14.1", + "Humanizer.Core.da": "2.14.1", + "Humanizer.Core.de": "2.14.1", + "Humanizer.Core.el": "2.14.1", + "Humanizer.Core.es": "2.14.1", + "Humanizer.Core.fa": "2.14.1", + "Humanizer.Core.fi-FI": "2.14.1", + "Humanizer.Core.fr": "2.14.1", + "Humanizer.Core.fr-BE": "2.14.1", + "Humanizer.Core.he": "2.14.1", + "Humanizer.Core.hr": "2.14.1", + "Humanizer.Core.hu": "2.14.1", + "Humanizer.Core.hy": "2.14.1", + "Humanizer.Core.id": "2.14.1", + "Humanizer.Core.is": "2.14.1", + "Humanizer.Core.it": "2.14.1", + "Humanizer.Core.ja": "2.14.1", + "Humanizer.Core.ko-KR": "2.14.1", + "Humanizer.Core.ku": "2.14.1", + "Humanizer.Core.lv": "2.14.1", + "Humanizer.Core.ms-MY": "2.14.1", + "Humanizer.Core.mt": "2.14.1", + "Humanizer.Core.nb": "2.14.1", + "Humanizer.Core.nb-NO": "2.14.1", + "Humanizer.Core.nl": "2.14.1", + "Humanizer.Core.pl": "2.14.1", + "Humanizer.Core.pt": "2.14.1", + "Humanizer.Core.ro": "2.14.1", + "Humanizer.Core.ru": "2.14.1", + "Humanizer.Core.sk": "2.14.1", + "Humanizer.Core.sl": "2.14.1", + "Humanizer.Core.sr": "2.14.1", + "Humanizer.Core.sr-Latn": "2.14.1", + "Humanizer.Core.sv": "2.14.1", + "Humanizer.Core.th-TH": "2.14.1", + "Humanizer.Core.tr": "2.14.1", + "Humanizer.Core.uk": "2.14.1", + "Humanizer.Core.uz-Cyrl-UZ": "2.14.1", + "Humanizer.Core.uz-Latn-UZ": "2.14.1", + "Humanizer.Core.vi": "2.14.1", + "Humanizer.Core.zh-CN": "2.14.1", + "Humanizer.Core.zh-Hans": "2.14.1", + "Humanizer.Core.zh-Hant": "2.14.1" + } + }, + "Humanizer.Core/2.14.1": { + "runtime": { + "lib/net6.0/Humanizer.dll": { + "assemblyVersion": "2.14.0.0", + "fileVersion": "2.14.1.48190" + } + } + }, + "Humanizer.Core.af/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/af/Humanizer.resources.dll": { + "locale": "af" + } + } + }, + "Humanizer.Core.ar/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/ar/Humanizer.resources.dll": { + "locale": "ar" + } + } + }, + "Humanizer.Core.az/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/az/Humanizer.resources.dll": { + "locale": "az" + } + } + }, + "Humanizer.Core.bg/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/bg/Humanizer.resources.dll": { + "locale": "bg" + } + } + }, + "Humanizer.Core.bn-BD/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/bn-BD/Humanizer.resources.dll": { + "locale": "bn-BD" + } + } + }, + "Humanizer.Core.cs/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/cs/Humanizer.resources.dll": { + "locale": "cs" + } + } + }, + "Humanizer.Core.da/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/da/Humanizer.resources.dll": { + "locale": "da" + } + } + }, + "Humanizer.Core.de/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/de/Humanizer.resources.dll": { + "locale": "de" + } + } + }, + "Humanizer.Core.el/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/el/Humanizer.resources.dll": { + "locale": "el" + } + } + }, + "Humanizer.Core.es/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/es/Humanizer.resources.dll": { + "locale": "es" + } + } + }, + "Humanizer.Core.fa/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/fa/Humanizer.resources.dll": { + "locale": "fa" + } + } + }, + "Humanizer.Core.fi-FI/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/fi-FI/Humanizer.resources.dll": { + "locale": "fi-FI" + } + } + }, + "Humanizer.Core.fr/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/fr/Humanizer.resources.dll": { + "locale": "fr" + } + } + }, + "Humanizer.Core.fr-BE/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/fr-BE/Humanizer.resources.dll": { + "locale": "fr-BE" + } + } + }, + "Humanizer.Core.he/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/he/Humanizer.resources.dll": { + "locale": "he" + } + } + }, + "Humanizer.Core.hr/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/hr/Humanizer.resources.dll": { + "locale": "hr" + } + } + }, + "Humanizer.Core.hu/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/hu/Humanizer.resources.dll": { + "locale": "hu" + } + } + }, + "Humanizer.Core.hy/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/hy/Humanizer.resources.dll": { + "locale": "hy" + } + } + }, + "Humanizer.Core.id/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/id/Humanizer.resources.dll": { + "locale": "id" + } + } + }, + "Humanizer.Core.is/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/is/Humanizer.resources.dll": { + "locale": "is" + } + } + }, + "Humanizer.Core.it/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/it/Humanizer.resources.dll": { + "locale": "it" + } + } + }, + "Humanizer.Core.ja/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/ja/Humanizer.resources.dll": { + "locale": "ja" + } + } + }, + "Humanizer.Core.ko-KR/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/netstandard2.0/ko-KR/Humanizer.resources.dll": { + "locale": "ko-KR" + } + } + }, + "Humanizer.Core.ku/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/ku/Humanizer.resources.dll": { + "locale": "ku" + } + } + }, + "Humanizer.Core.lv/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/lv/Humanizer.resources.dll": { + "locale": "lv" + } + } + }, + "Humanizer.Core.ms-MY/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/netstandard2.0/ms-MY/Humanizer.resources.dll": { + "locale": "ms-MY" + } + } + }, + "Humanizer.Core.mt/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/netstandard2.0/mt/Humanizer.resources.dll": { + "locale": "mt" + } + } + }, + "Humanizer.Core.nb/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/nb/Humanizer.resources.dll": { + "locale": "nb" + } + } + }, + "Humanizer.Core.nb-NO/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/nb-NO/Humanizer.resources.dll": { + "locale": "nb-NO" + } + } + }, + "Humanizer.Core.nl/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/nl/Humanizer.resources.dll": { + "locale": "nl" + } + } + }, + "Humanizer.Core.pl/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/pl/Humanizer.resources.dll": { + "locale": "pl" + } + } + }, + "Humanizer.Core.pt/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/pt/Humanizer.resources.dll": { + "locale": "pt" + } + } + }, + "Humanizer.Core.ro/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/ro/Humanizer.resources.dll": { + "locale": "ro" + } + } + }, + "Humanizer.Core.ru/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/ru/Humanizer.resources.dll": { + "locale": "ru" + } + } + }, + "Humanizer.Core.sk/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/sk/Humanizer.resources.dll": { + "locale": "sk" + } + } + }, + "Humanizer.Core.sl/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/sl/Humanizer.resources.dll": { + "locale": "sl" + } + } + }, + "Humanizer.Core.sr/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/sr/Humanizer.resources.dll": { + "locale": "sr" + } + } + }, + "Humanizer.Core.sr-Latn/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/sr-Latn/Humanizer.resources.dll": { + "locale": "sr-Latn" + } + } + }, + "Humanizer.Core.sv/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/sv/Humanizer.resources.dll": { + "locale": "sv" + } + } + }, + "Humanizer.Core.th-TH/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/netstandard2.0/th-TH/Humanizer.resources.dll": { + "locale": "th-TH" + } + } + }, + "Humanizer.Core.tr/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/tr/Humanizer.resources.dll": { + "locale": "tr" + } + } + }, + "Humanizer.Core.uk/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/uk/Humanizer.resources.dll": { + "locale": "uk" + } + } + }, + "Humanizer.Core.uz-Cyrl-UZ/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/uz-Cyrl-UZ/Humanizer.resources.dll": { + "locale": "uz-Cyrl-UZ" + } + } + }, + "Humanizer.Core.uz-Latn-UZ/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/uz-Latn-UZ/Humanizer.resources.dll": { + "locale": "uz-Latn-UZ" + } + } + }, + "Humanizer.Core.vi/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/vi/Humanizer.resources.dll": { + "locale": "vi" + } + } + }, + "Humanizer.Core.zh-CN/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/zh-CN/Humanizer.resources.dll": { + "locale": "zh-CN" + } + } + }, + "Humanizer.Core.zh-Hans/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/zh-Hans/Humanizer.resources.dll": { + "locale": "zh-Hans" + } + } + }, + "Humanizer.Core.zh-Hant/2.14.1": { + "dependencies": { + "Humanizer.Core": "2.14.1" + }, + "resources": { + "lib/net6.0/zh-Hant/Humanizer.resources.dll": { + "locale": "zh-Hant" + } + } + }, + "Newtonsoft.Json/13.0.3": { + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.3.27908" + } + } + } + } + }, + "libraries": { + "dotnetapp/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "runtimepack.Microsoft.NETCore.App.Runtime.win-x64/8.0.14": { + "type": "runtimepack", + "serviceable": false, + "sha512": "" + }, + "Humanizer/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-/FUTD3cEceAAmJSCPN9+J+VhGwmL/C12jvwlyM1DFXShEMsBzvLzLqSrJ2rb+k/W2znKw7JyflZgZpyE+tI7lA==", + "path": "humanizer/2.14.1", + "hashPath": "humanizer.2.14.1.nupkg.sha512" + }, + "Humanizer.Core/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-lQKvtaTDOXnoVJ20ibTuSIOf2i0uO0MPbDhd1jm238I+U/2ZnRENj0cktKZhtchBMtCUSRQ5v4xBCUbKNmyVMw==", + "path": "humanizer.core/2.14.1", + "hashPath": "humanizer.core.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.af/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-BoQHyu5le+xxKOw+/AUM7CLXneM/Bh3++0qh1u0+D95n6f9eGt9kNc8LcAHLIOwId7Sd5hiAaaav0Nimj3peNw==", + "path": "humanizer.core.af/2.14.1", + "hashPath": "humanizer.core.af.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.ar/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3d1V10LDtmqg5bZjWkA/EkmGFeSfNBcyCH+TiHcHP+HGQQmRq3eBaLcLnOJbVQVn3Z6Ak8GOte4RX4kVCxQlFA==", + "path": "humanizer.core.ar/2.14.1", + "hashPath": "humanizer.core.ar.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.az/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8Z/tp9PdHr/K2Stve2Qs/7uqWPWLUK9D8sOZDNzyv42e20bSoJkHFn7SFoxhmaoVLJwku2jp6P7HuwrfkrP18Q==", + "path": "humanizer.core.az/2.14.1", + "hashPath": "humanizer.core.az.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.bg/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-S+hIEHicrOcbV2TBtyoPp1AVIGsBzlarOGThhQYCnP6QzEYo/5imtok6LMmhZeTnBFoKhM8yJqRfvJ5yqVQKSQ==", + "path": "humanizer.core.bg/2.14.1", + "hashPath": "humanizer.core.bg.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.bn-BD/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-U3bfj90tnUDRKlL1ZFlzhCHoVgpTcqUlTQxjvGCaFKb+734TTu3nkHUWVZltA1E/swTvimo/aXLtkxnLFrc0EQ==", + "path": "humanizer.core.bn-bd/2.14.1", + "hashPath": "humanizer.core.bn-bd.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.cs/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-jWrQkiCTy3L2u1T86cFkgijX6k7hoB0pdcFMWYaSZnm6rvG/XJE40tfhYyKhYYgIc1x9P2GO5AC7xXvFnFdqMQ==", + "path": "humanizer.core.cs/2.14.1", + "hashPath": "humanizer.core.cs.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.da/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-5o0rJyE/2wWUUphC79rgYDnif/21MKTTx9LIzRVz9cjCIVFrJ2bDyR2gapvI9D6fjoyvD1NAfkN18SHBsO8S9g==", + "path": "humanizer.core.da/2.14.1", + "hashPath": "humanizer.core.da.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.de/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-9JD/p+rqjb8f5RdZ3aEJqbjMYkbk4VFii2QDnnOdNo6ywEfg/A5YeOQ55CaBJmy7KvV4tOK4+qHJnX/tg3Z54A==", + "path": "humanizer.core.de/2.14.1", + "hashPath": "humanizer.core.de.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.el/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Xmv6sTL5mqjOWGGpqY7bvbfK5RngaUHSa8fYDGSLyxY9mGdNbDcasnRnMOvi0SxJS9gAqBCn21Xi90n2SHZbFA==", + "path": "humanizer.core.el/2.14.1", + "hashPath": "humanizer.core.el.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.es/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-e//OIAeMB7pjBV1HqqI4pM2Bcw3Jwgpyz9G5Fi4c+RJvhqFwztoWxW57PzTnNJE2lbhGGLQZihFZjsbTUsbczA==", + "path": "humanizer.core.es/2.14.1", + "hashPath": "humanizer.core.es.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.fa/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-nzDOj1x0NgjXMjsQxrET21t1FbdoRYujzbmZoR8u8ou5CBWY1UNca0j6n/PEJR/iUbt4IxstpszRy41wL/BrpA==", + "path": "humanizer.core.fa/2.14.1", + "hashPath": "humanizer.core.fa.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.fi-FI/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Vnxxx4LUhp3AzowYi6lZLAA9Lh8UqkdwRh4IE2qDXiVpbo08rSbokATaEzFS+o+/jCNZBmoyyyph3vgmcSzhhQ==", + "path": "humanizer.core.fi-fi/2.14.1", + "hashPath": "humanizer.core.fi-fi.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.fr/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-2p4g0BYNzFS3u9SOIDByp2VClYKO0K1ecDV4BkB9EYdEPWfFODYnF+8CH8LpUrpxL2TuWo2fiFx/4Jcmrnkbpg==", + "path": "humanizer.core.fr/2.14.1", + "hashPath": "humanizer.core.fr.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.fr-BE/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-o6R3SerxCRn5Ij8nCihDNMGXlaJ/1AqefteAssgmU2qXYlSAGdhxmnrQAXZUDlE4YWt/XQ6VkNLtH7oMqsSPFQ==", + "path": "humanizer.core.fr-be/2.14.1", + "hashPath": "humanizer.core.fr-be.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.he/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-FPsAhy7Iw6hb+ZitLgYC26xNcgGAHXb0V823yFAzcyoL5ozM+DCJtYfDPYiOpsJhEZmKFTM9No0jUn1M89WGvg==", + "path": "humanizer.core.he/2.14.1", + "hashPath": "humanizer.core.he.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.hr/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-chnaD89yOlST142AMkAKLuzRcV5df3yyhDyRU5rypDiqrq2HN8y1UR3h1IicEAEtXLoOEQyjSAkAQ6QuXkn7aw==", + "path": "humanizer.core.hr/2.14.1", + "hashPath": "humanizer.core.hr.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.hu/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-hAfnaoF9LTGU/CmFdbnvugN4tIs8ppevVMe3e5bD24+tuKsggMc5hYta9aiydI8JH9JnuVmxvNI4DJee1tK05A==", + "path": "humanizer.core.hu/2.14.1", + "hashPath": "humanizer.core.hu.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.hy/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-sVIKxOiSBUb4gStRHo9XwwAg9w7TNvAXbjy176gyTtaTiZkcjr9aCPziUlYAF07oNz6SdwdC2mwJBGgvZ0Sl2g==", + "path": "humanizer.core.hy/2.14.1", + "hashPath": "humanizer.core.hy.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.id/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4Zl3GTvk3a49Ia/WDNQ97eCupjjQRs2iCIZEQdmkiqyaLWttfb+cYXDMGthP42nufUL0SRsvBctN67oSpnXtsg==", + "path": "humanizer.core.id/2.14.1", + "hashPath": "humanizer.core.id.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.is/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-R67A9j/nNgcWzU7gZy1AJ07ABSLvogRbqOWvfRDn4q6hNdbg/mjGjZBp4qCTPnB2mHQQTCKo3oeCUayBCNIBCw==", + "path": "humanizer.core.is/2.14.1", + "hashPath": "humanizer.core.is.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.it/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-jYxGeN4XIKHVND02FZ+Woir3CUTyBhLsqxu9iqR/9BISArkMf1Px6i5pRZnvq4fc5Zn1qw71GKKoCaHDJBsLFw==", + "path": "humanizer.core.it/2.14.1", + "hashPath": "humanizer.core.it.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.ja/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-TM3ablFNoYx4cYJybmRgpDioHpiKSD7q0QtMrmpsqwtiiEsdW5zz/q4PolwAczFnvrKpN6nBXdjnPPKVet93ng==", + "path": "humanizer.core.ja/2.14.1", + "hashPath": "humanizer.core.ja.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.ko-KR/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-CtvwvK941k/U0r8PGdEuBEMdW6jv/rBiA9tUhakC7Zd2rA/HCnDcbr1DiNZ+/tRshnhzxy/qwmpY8h4qcAYCtQ==", + "path": "humanizer.core.ko-kr/2.14.1", + "hashPath": "humanizer.core.ko-kr.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.ku/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-vHmzXcVMe+LNrF9txpdHzpG7XJX65SiN9GQd/Zkt6gsGIIEeECHrkwCN5Jnlkddw2M/b0HS4SNxdR1GrSn7uCA==", + "path": "humanizer.core.ku/2.14.1", + "hashPath": "humanizer.core.ku.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.lv/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-E1/KUVnYBS1bdOTMNDD7LV/jdoZv/fbWTLPtvwdMtSdqLyRTllv6PGM9xVQoFDYlpvVGtEl/09glCojPHw8ffA==", + "path": "humanizer.core.lv/2.14.1", + "hashPath": "humanizer.core.lv.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.ms-MY/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-vX8oq9HnYmAF7bek4aGgGFJficHDRTLgp/EOiPv9mBZq0i4SA96qVMYSjJ2YTaxs7Eljqit7pfpE2nmBhY5Fnw==", + "path": "humanizer.core.ms-my/2.14.1", + "hashPath": "humanizer.core.ms-my.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.mt/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-pEgTBzUI9hzemF7xrIZigl44LidTUhNu4x/P6M9sAwZjkUF0mMkbpxKkaasOql7lLafKrnszs0xFfaxQyzeuZQ==", + "path": "humanizer.core.mt/2.14.1", + "hashPath": "humanizer.core.mt.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.nb/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-mbs3m6JJq53ssLqVPxNfqSdTxAcZN3njlG8yhJVx83XVedpTe1ECK9aCa8FKVOXv93Gl+yRHF82Hw9T9LWv2hw==", + "path": "humanizer.core.nb/2.14.1", + "hashPath": "humanizer.core.nb.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.nb-NO/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-AsJxrrVYmIMbKDGe8W6Z6//wKv9dhWH7RsTcEHSr4tQt/80pcNvLi0hgD3fqfTtg0tWKtgch2cLf4prorEV+5A==", + "path": "humanizer.core.nb-no/2.14.1", + "hashPath": "humanizer.core.nb-no.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.nl/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-24b0OUdzJxfoqiHPCtYnR5Y4l/s4Oh7KW7uDp+qX25NMAHLCGog2eRfA7p2kRJp8LvnynwwQxm2p534V9m55wQ==", + "path": "humanizer.core.nl/2.14.1", + "hashPath": "humanizer.core.nl.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.pl/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-17mJNYaBssENVZyQHduiq+bvdXS0nhZJGEXtPKoMhKv3GD//WO0mEfd9wjEBsWCSmWI7bjRqhCidxzN+YtJmsg==", + "path": "humanizer.core.pl/2.14.1", + "hashPath": "humanizer.core.pl.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.pt/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-8HB8qavcVp2la1GJX6t+G9nDYtylPKzyhxr9LAooIei9MnQvNsjEiIE4QvHoeDZ4weuQ9CsPg1c211XUMVEZ4A==", + "path": "humanizer.core.pt/2.14.1", + "hashPath": "humanizer.core.pt.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.ro/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-psXNOcA6R8fSHoQYhpBTtTTYiOk8OBoN3PKCEDgsJKIyeY5xuK81IBdGi77qGZMu/OwBRQjQCBMtPJb0f4O1+A==", + "path": "humanizer.core.ro/2.14.1", + "hashPath": "humanizer.core.ro.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.ru/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-zm245xUWrajSN2t9H7BTf84/2APbUkKlUJpcdgsvTdAysr1ag9fi1APu6JEok39RRBXDfNRVZHawQ/U8X0pSvQ==", + "path": "humanizer.core.ru/2.14.1", + "hashPath": "humanizer.core.ru.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.sk/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Ncw24Vf3ioRnbU4MsMFHafkyYi8JOnTqvK741GftlQvAbULBoTz2+e7JByOaasqeSi0KfTXeegJO+5Wk1c0Mbw==", + "path": "humanizer.core.sk/2.14.1", + "hashPath": "humanizer.core.sk.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.sl/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-l8sUy4ciAIbVThWNL0atzTS2HWtv8qJrsGWNlqrEKmPwA4SdKolSqnTes9V89fyZTc2Q43jK8fgzVE2C7t009A==", + "path": "humanizer.core.sl/2.14.1", + "hashPath": "humanizer.core.sl.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.sr/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-rnNvhpkOrWEymy7R/MiFv7uef8YO5HuXDyvojZ7JpijHWA5dXuVXooCOiA/3E93fYa3pxDuG2OQe4M/olXbQ7w==", + "path": "humanizer.core.sr/2.14.1", + "hashPath": "humanizer.core.sr.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.sr-Latn/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-nuy/ykpk974F8ItoQMS00kJPr2dFNjOSjgzCwfysbu7+gjqHmbLcYs7G4kshLwdA4AsVncxp99LYeJgoh1JF5g==", + "path": "humanizer.core.sr-latn/2.14.1", + "hashPath": "humanizer.core.sr-latn.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.sv/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-E53+tpAG0RCp+cSSI7TfBPC+NnsEqUuoSV0sU+rWRXWr9MbRWx1+Zj02XMojqjGzHjjOrBFBBio6m74seFl0AA==", + "path": "humanizer.core.sv/2.14.1", + "hashPath": "humanizer.core.sv.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.th-TH/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-eSevlJtvs1r4vQarNPfZ2kKDp/xMhuD00tVVzRXkSh1IAZbBJI/x2ydxUOwfK9bEwEp+YjvL1Djx2+kw7ziu7g==", + "path": "humanizer.core.th-th/2.14.1", + "hashPath": "humanizer.core.th-th.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.tr/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-rQ8N+o7yFcFqdbtu1mmbrXFi8TQ+uy+fVH9OPI0CI3Cu1om5hUU/GOMC3hXsTCI6d79y4XX+0HbnD7FT5khegA==", + "path": "humanizer.core.tr/2.14.1", + "hashPath": "humanizer.core.tr.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.uk/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-2uEfujwXKNm6bdpukaLtEJD+04uUtQD65nSGCetA1fYNizItEaIBUboNfr3GzJxSMQotNwGVM3+nSn8jTd0VSg==", + "path": "humanizer.core.uk/2.14.1", + "hashPath": "humanizer.core.uk.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.uz-Cyrl-UZ/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-TD3ME2sprAvFqk9tkWrvSKx5XxEMlAn1sjk+cYClSWZlIMhQQ2Bp/w0VjX1Kc5oeKjxRAnR7vFcLUFLiZIDk9Q==", + "path": "humanizer.core.uz-cyrl-uz/2.14.1", + "hashPath": "humanizer.core.uz-cyrl-uz.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.uz-Latn-UZ/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-/kHAoF4g0GahnugZiEMpaHlxb+W6jCEbWIdsq9/I1k48ULOsl/J0pxZj93lXC3omGzVF1BTVIeAtv5fW06Phsg==", + "path": "humanizer.core.uz-latn-uz/2.14.1", + "hashPath": "humanizer.core.uz-latn-uz.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.vi/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-rsQNh9rmHMBtnsUUlJbShMsIMGflZtPmrMM6JNDw20nhsvqfrdcoDD8cMnLAbuSovtc3dP+swRmLQzKmXDTVPA==", + "path": "humanizer.core.vi/2.14.1", + "hashPath": "humanizer.core.vi.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.zh-CN/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-uH2dWhrgugkCjDmduLdAFO9w1Mo0q07EuvM0QiIZCVm6FMCu/lGv2fpMu4GX+4HLZ6h5T2Pg9FIdDLCPN2a67w==", + "path": "humanizer.core.zh-cn/2.14.1", + "hashPath": "humanizer.core.zh-cn.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.zh-Hans/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-WH6IhJ8V1UBG7rZXQk3dZUoP2gsi8a0WkL8xL0sN6WGiv695s8nVcmab9tWz20ySQbuzp0UkSxUQFi5jJHIpOQ==", + "path": "humanizer.core.zh-hans/2.14.1", + "hashPath": "humanizer.core.zh-hans.2.14.1.nupkg.sha512" + }, + "Humanizer.Core.zh-Hant/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-VIXB7HCUC34OoaGnO3HJVtSv2/wljPhjV7eKH4+TFPgQdJj2lvHNKY41Dtg0Bphu7X5UaXFR4zrYYyo+GNOjbA==", + "path": "humanizer.core.zh-hant/2.14.1", + "hashPath": "humanizer.core.zh-hant.2.14.1.nupkg.sha512" + }, + "Newtonsoft.Json/13.0.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", + "path": "newtonsoft.json/13.0.3", + "hashPath": "newtonsoft.json.13.0.3.nupkg.sha512" + } + }, + "runtimes": { + "win-x64": [ + "win", + "any", + "base" + ] + } +} \ No newline at end of file