mirror of
https://github.com/anchore/syft.git
synced 2026-02-12 02:26:42 +01:00
better .NET cpe generation (#3764)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
parent
ad9928cb2a
commit
40dd5d0bbd
@ -305,181 +305,6 @@ func TestCataloger(t *testing.T) {
|
||||
"runtimepack.Microsoft.NETCore.App.Runtime.win-x64 @ 8.0.14 (/app/dotnetapp.deps.json) [dependency-of] dotnetapp @ 1.0.0 (/app/dotnetapp.deps.json)",
|
||||
)
|
||||
|
||||
var net8AppExpectedBinarySelfContainedRelationships []string
|
||||
net8AppExpectedBinarySelfContainedRelationships = append(net8AppExpectedBinarySelfContainedRelationships, net8AppBinaryOnlyPkgs...)
|
||||
net8AppExpectedBinarySelfContainedRelationships = append(net8AppExpectedBinarySelfContainedRelationships,
|
||||
// include the runtime libs...
|
||||
"Microsoft.CSharp @ 8.0.1425.11118 (/app/Microsoft.CSharp.dll)",
|
||||
"Microsoft.VisualBasic @ 8.0.1425.11118 (/app/Microsoft.VisualBasic.dll)",
|
||||
"Microsoft.VisualBasic.Core @ 13.0.1425.11118 (/app/Microsoft.VisualBasic.Core.dll)",
|
||||
"Microsoft.Win32.Primitives @ 8.0.1425.11118 (/app/Microsoft.Win32.Primitives.dll)",
|
||||
"Microsoft.Win32.Registry @ 8.0.1425.11118 (/app/Microsoft.Win32.Registry.dll)",
|
||||
"System @ 8.0.1425.11118 (/app/System.dll)",
|
||||
"System.AppContext @ 8.0.1425.11118 (/app/System.AppContext.dll)",
|
||||
"System.Buffers @ 8.0.1425.11118 (/app/System.Buffers.dll)",
|
||||
"System.Collections @ 8.0.1425.11118 (/app/System.Collections.dll)",
|
||||
"System.Collections.Concurrent @ 8.0.1425.11118 (/app/System.Collections.Concurrent.dll)",
|
||||
"System.Collections.Immutable @ 8.0.1425.11118 (/app/System.Collections.Immutable.dll)",
|
||||
"System.Collections.NonGeneric @ 8.0.1425.11118 (/app/System.Collections.NonGeneric.dll)",
|
||||
"System.Collections.Specialized @ 8.0.1425.11118 (/app/System.Collections.Specialized.dll)",
|
||||
"System.ComponentModel @ 8.0.1425.11118 (/app/System.ComponentModel.dll)",
|
||||
"System.ComponentModel.Annotations @ 8.0.1425.11118 (/app/System.ComponentModel.Annotations.dll)",
|
||||
"System.ComponentModel.DataAnnotations @ 8.0.1425.11118 (/app/System.ComponentModel.DataAnnotations.dll)",
|
||||
"System.ComponentModel.EventBasedAsync @ 8.0.1425.11118 (/app/System.ComponentModel.EventBasedAsync.dll)",
|
||||
"System.ComponentModel.Primitives @ 8.0.1425.11118 (/app/System.ComponentModel.Primitives.dll)",
|
||||
"System.ComponentModel.TypeConverter @ 8.0.1425.11118 (/app/System.ComponentModel.TypeConverter.dll)",
|
||||
"System.Configuration @ 8.0.1425.11118 (/app/System.Configuration.dll)",
|
||||
"System.Console @ 8.0.1425.11118 (/app/System.Console.dll)",
|
||||
"System.Core @ 8.0.1425.11118 (/app/System.Core.dll)",
|
||||
"System.Data @ 8.0.1425.11118 (/app/System.Data.dll)",
|
||||
"System.Data.Common @ 8.0.1425.11118 (/app/System.Data.Common.dll)",
|
||||
"System.Data.DataSetExtensions @ 8.0.1425.11118 (/app/System.Data.DataSetExtensions.dll)",
|
||||
"System.Diagnostics.Contracts @ 8.0.1425.11118 (/app/System.Diagnostics.Contracts.dll)",
|
||||
"System.Diagnostics.Debug @ 8.0.1425.11118 (/app/System.Diagnostics.Debug.dll)",
|
||||
"System.Diagnostics.DiagnosticSource @ 8.0.1425.11118 (/app/System.Diagnostics.DiagnosticSource.dll)",
|
||||
"System.Diagnostics.FileVersionInfo @ 8.0.1425.11118 (/app/System.Diagnostics.FileVersionInfo.dll)",
|
||||
"System.Diagnostics.Process @ 8.0.1425.11118 (/app/System.Diagnostics.Process.dll)",
|
||||
"System.Diagnostics.StackTrace @ 8.0.1425.11118 (/app/System.Diagnostics.StackTrace.dll)",
|
||||
"System.Diagnostics.TextWriterTraceListener @ 8.0.1425.11118 (/app/System.Diagnostics.TextWriterTraceListener.dll)",
|
||||
"System.Diagnostics.Tools @ 8.0.1425.11118 (/app/System.Diagnostics.Tools.dll)",
|
||||
"System.Diagnostics.TraceSource @ 8.0.1425.11118 (/app/System.Diagnostics.TraceSource.dll)",
|
||||
"System.Diagnostics.Tracing @ 8.0.1425.11118 (/app/System.Diagnostics.Tracing.dll)",
|
||||
"System.Drawing @ 8.0.1425.11118 (/app/System.Drawing.dll)",
|
||||
"System.Drawing.Primitives @ 8.0.1425.11118 (/app/System.Drawing.Primitives.dll)",
|
||||
"System.Dynamic.Runtime @ 8.0.1425.11118 (/app/System.Dynamic.Runtime.dll)",
|
||||
"System.Formats.Asn1 @ 8.0.1425.11118 (/app/System.Formats.Asn1.dll)",
|
||||
"System.Formats.Tar @ 8.0.1425.11118 (/app/System.Formats.Tar.dll)",
|
||||
"System.Globalization @ 8.0.1425.11118 (/app/System.Globalization.dll)",
|
||||
"System.Globalization.Calendars @ 8.0.1425.11118 (/app/System.Globalization.Calendars.dll)",
|
||||
"System.Globalization.Extensions @ 8.0.1425.11118 (/app/System.Globalization.Extensions.dll)",
|
||||
"System.IO @ 8.0.1425.11118 (/app/System.IO.dll)",
|
||||
"System.IO.Compression @ 8.0.1425.11118 (/app/System.IO.Compression.dll)",
|
||||
"System.IO.Compression.Brotli @ 8.0.1425.11118 (/app/System.IO.Compression.Brotli.dll)",
|
||||
"System.IO.Compression.FileSystem @ 8.0.1425.11118 (/app/System.IO.Compression.FileSystem.dll)",
|
||||
"System.IO.Compression.ZipFile @ 8.0.1425.11118 (/app/System.IO.Compression.ZipFile.dll)",
|
||||
"System.IO.FileSystem @ 8.0.1425.11118 (/app/System.IO.FileSystem.dll)",
|
||||
"System.IO.FileSystem.AccessControl @ 8.0.1425.11118 (/app/System.IO.FileSystem.AccessControl.dll)",
|
||||
"System.IO.FileSystem.DriveInfo @ 8.0.1425.11118 (/app/System.IO.FileSystem.DriveInfo.dll)",
|
||||
"System.IO.FileSystem.Primitives @ 8.0.1425.11118 (/app/System.IO.FileSystem.Primitives.dll)",
|
||||
"System.IO.FileSystem.Watcher @ 8.0.1425.11118 (/app/System.IO.FileSystem.Watcher.dll)",
|
||||
"System.IO.IsolatedStorage @ 8.0.1425.11118 (/app/System.IO.IsolatedStorage.dll)",
|
||||
"System.IO.MemoryMappedFiles @ 8.0.1425.11118 (/app/System.IO.MemoryMappedFiles.dll)",
|
||||
"System.IO.Pipes @ 8.0.1425.11118 (/app/System.IO.Pipes.dll)",
|
||||
"System.IO.Pipes.AccessControl @ 8.0.1425.11118 (/app/System.IO.Pipes.AccessControl.dll)",
|
||||
"System.IO.UnmanagedMemoryStream @ 8.0.1425.11118 (/app/System.IO.UnmanagedMemoryStream.dll)",
|
||||
"System.Linq @ 8.0.1425.11118 (/app/System.Linq.dll)",
|
||||
"System.Linq.Expressions @ 8.0.1425.11118 (/app/System.Linq.Expressions.dll)",
|
||||
"System.Linq.Parallel @ 8.0.1425.11118 (/app/System.Linq.Parallel.dll)",
|
||||
"System.Linq.Queryable @ 8.0.1425.11118 (/app/System.Linq.Queryable.dll)",
|
||||
"System.Memory @ 8.0.1425.11118 (/app/System.Memory.dll)",
|
||||
"System.Net @ 8.0.1425.11118 (/app/System.Net.dll)",
|
||||
"System.Net.Http @ 8.0.1425.11118 (/app/System.Net.Http.dll)",
|
||||
"System.Net.Http.Json @ 8.0.1425.11118 (/app/System.Net.Http.Json.dll)",
|
||||
"System.Net.HttpListener @ 8.0.1425.11118 (/app/System.Net.HttpListener.dll)",
|
||||
"System.Net.Mail @ 8.0.1425.11118 (/app/System.Net.Mail.dll)",
|
||||
"System.Net.NameResolution @ 8.0.1425.11118 (/app/System.Net.NameResolution.dll)",
|
||||
"System.Net.NetworkInformation @ 8.0.1425.11118 (/app/System.Net.NetworkInformation.dll)",
|
||||
"System.Net.Ping @ 8.0.1425.11118 (/app/System.Net.Ping.dll)",
|
||||
"System.Net.Primitives @ 8.0.1425.11118 (/app/System.Net.Primitives.dll)",
|
||||
"System.Net.Quic @ 8.0.1425.11118 (/app/System.Net.Quic.dll)",
|
||||
"System.Net.Requests @ 8.0.1425.11118 (/app/System.Net.Requests.dll)",
|
||||
"System.Net.Security @ 8.0.1425.11118 (/app/System.Net.Security.dll)",
|
||||
"System.Net.ServicePoint @ 8.0.1425.11118 (/app/System.Net.ServicePoint.dll)",
|
||||
"System.Net.Sockets @ 8.0.1425.11118 (/app/System.Net.Sockets.dll)",
|
||||
"System.Net.WebClient @ 8.0.1425.11118 (/app/System.Net.WebClient.dll)",
|
||||
"System.Net.WebHeaderCollection @ 8.0.1425.11118 (/app/System.Net.WebHeaderCollection.dll)",
|
||||
"System.Net.WebProxy @ 8.0.1425.11118 (/app/System.Net.WebProxy.dll)",
|
||||
"System.Net.WebSockets @ 8.0.1425.11118 (/app/System.Net.WebSockets.dll)",
|
||||
"System.Net.WebSockets.Client @ 8.0.1425.11118 (/app/System.Net.WebSockets.Client.dll)",
|
||||
"System.Numerics @ 8.0.1425.11118 (/app/System.Numerics.dll)",
|
||||
"System.Numerics.Vectors @ 8.0.1425.11118 (/app/System.Numerics.Vectors.dll)",
|
||||
"System.ObjectModel @ 8.0.1425.11118 (/app/System.ObjectModel.dll)",
|
||||
"System.Private.CoreLib @ 8.0.1425.11118 (/app/System.Private.CoreLib.dll)",
|
||||
"System.Private.DataContractSerialization @ 8.0.1425.11118 (/app/System.Private.DataContractSerialization.dll)",
|
||||
"System.Private.Uri @ 8.0.1425.11118 (/app/System.Private.Uri.dll)",
|
||||
"System.Private.Xml @ 8.0.1425.11118 (/app/System.Private.Xml.dll)",
|
||||
"System.Private.Xml.Linq @ 8.0.1425.11118 (/app/System.Private.Xml.Linq.dll)",
|
||||
"System.Reflection @ 8.0.1425.11118 (/app/System.Reflection.dll)",
|
||||
"System.Reflection.DispatchProxy @ 8.0.1425.11118 (/app/System.Reflection.DispatchProxy.dll)",
|
||||
"System.Reflection.Emit @ 8.0.1425.11118 (/app/System.Reflection.Emit.dll)",
|
||||
"System.Reflection.Emit.ILGeneration @ 8.0.1425.11118 (/app/System.Reflection.Emit.ILGeneration.dll)",
|
||||
"System.Reflection.Emit.Lightweight @ 8.0.1425.11118 (/app/System.Reflection.Emit.Lightweight.dll)",
|
||||
"System.Reflection.Extensions @ 8.0.1425.11118 (/app/System.Reflection.Extensions.dll)",
|
||||
"System.Reflection.Metadata @ 8.0.1425.11118 (/app/System.Reflection.Metadata.dll)",
|
||||
"System.Reflection.Primitives @ 8.0.1425.11118 (/app/System.Reflection.Primitives.dll)",
|
||||
"System.Reflection.TypeExtensions @ 8.0.1425.11118 (/app/System.Reflection.TypeExtensions.dll)",
|
||||
"System.Resources.Reader @ 8.0.1425.11118 (/app/System.Resources.Reader.dll)",
|
||||
"System.Resources.ResourceManager @ 8.0.1425.11118 (/app/System.Resources.ResourceManager.dll)",
|
||||
"System.Resources.Writer @ 8.0.1425.11118 (/app/System.Resources.Writer.dll)",
|
||||
"System.Runtime @ 8.0.1425.11118 (/app/System.Runtime.dll)",
|
||||
"System.Runtime.CompilerServices.Unsafe @ 8.0.1425.11118 (/app/System.Runtime.CompilerServices.Unsafe.dll)",
|
||||
"System.Runtime.CompilerServices.VisualC @ 8.0.1425.11118 (/app/System.Runtime.CompilerServices.VisualC.dll)",
|
||||
"System.Runtime.Extensions @ 8.0.1425.11118 (/app/System.Runtime.Extensions.dll)",
|
||||
"System.Runtime.Handles @ 8.0.1425.11118 (/app/System.Runtime.Handles.dll)",
|
||||
"System.Runtime.InteropServices @ 8.0.1425.11118 (/app/System.Runtime.InteropServices.dll)",
|
||||
"System.Runtime.InteropServices.JavaScript @ 8.0.1425.11118 (/app/System.Runtime.InteropServices.JavaScript.dll)",
|
||||
"System.Runtime.InteropServices.RuntimeInformation @ 8.0.1425.11118 (/app/System.Runtime.InteropServices.RuntimeInformation.dll)",
|
||||
"System.Runtime.Intrinsics @ 8.0.1425.11118 (/app/System.Runtime.Intrinsics.dll)",
|
||||
"System.Runtime.Loader @ 8.0.1425.11118 (/app/System.Runtime.Loader.dll)",
|
||||
"System.Runtime.Numerics @ 8.0.1425.11118 (/app/System.Runtime.Numerics.dll)",
|
||||
"System.Runtime.Serialization @ 8.0.1425.11118 (/app/System.Runtime.Serialization.dll)",
|
||||
"System.Runtime.Serialization.Formatters @ 8.0.1425.11118 (/app/System.Runtime.Serialization.Formatters.dll)",
|
||||
"System.Runtime.Serialization.Json @ 8.0.1425.11118 (/app/System.Runtime.Serialization.Json.dll)",
|
||||
"System.Runtime.Serialization.Primitives @ 8.0.1425.11118 (/app/System.Runtime.Serialization.Primitives.dll)",
|
||||
"System.Runtime.Serialization.Xml @ 8.0.1425.11118 (/app/System.Runtime.Serialization.Xml.dll)",
|
||||
"System.Security @ 8.0.1425.11118 (/app/System.Security.dll)",
|
||||
"System.Security.AccessControl @ 8.0.1425.11118 (/app/System.Security.AccessControl.dll)",
|
||||
"System.Security.Claims @ 8.0.1425.11118 (/app/System.Security.Claims.dll)",
|
||||
"System.Security.Cryptography @ 8.0.1425.11118 (/app/System.Security.Cryptography.dll)",
|
||||
"System.Security.Cryptography.Algorithms @ 8.0.1425.11118 (/app/System.Security.Cryptography.Algorithms.dll)",
|
||||
"System.Security.Cryptography.Cng @ 8.0.1425.11118 (/app/System.Security.Cryptography.Cng.dll)",
|
||||
"System.Security.Cryptography.Csp @ 8.0.1425.11118 (/app/System.Security.Cryptography.Csp.dll)",
|
||||
"System.Security.Cryptography.Encoding @ 8.0.1425.11118 (/app/System.Security.Cryptography.Encoding.dll)",
|
||||
"System.Security.Cryptography.OpenSsl @ 8.0.1425.11118 (/app/System.Security.Cryptography.OpenSsl.dll)",
|
||||
"System.Security.Cryptography.Primitives @ 8.0.1425.11118 (/app/System.Security.Cryptography.Primitives.dll)",
|
||||
"System.Security.Cryptography.X509Certificates @ 8.0.1425.11118 (/app/System.Security.Cryptography.X509Certificates.dll)",
|
||||
"System.Security.Principal @ 8.0.1425.11118 (/app/System.Security.Principal.dll)",
|
||||
"System.Security.Principal.Windows @ 8.0.1425.11118 (/app/System.Security.Principal.Windows.dll)",
|
||||
"System.Security.SecureString @ 8.0.1425.11118 (/app/System.Security.SecureString.dll)",
|
||||
"System.ServiceModel.Web @ 8.0.1425.11118 (/app/System.ServiceModel.Web.dll)",
|
||||
"System.ServiceProcess @ 8.0.1425.11118 (/app/System.ServiceProcess.dll)",
|
||||
"System.Text.Encoding @ 8.0.1425.11118 (/app/System.Text.Encoding.dll)",
|
||||
"System.Text.Encoding.CodePages @ 8.0.1425.11118 (/app/System.Text.Encoding.CodePages.dll)",
|
||||
"System.Text.Encoding.Extensions @ 8.0.1425.11118 (/app/System.Text.Encoding.Extensions.dll)",
|
||||
"System.Text.Encodings.Web @ 8.0.1425.11118 (/app/System.Text.Encodings.Web.dll)",
|
||||
"System.Text.Json @ 8.0.1425.11118 (/app/System.Text.Json.dll)",
|
||||
"System.Text.RegularExpressions @ 8.0.1425.11118 (/app/System.Text.RegularExpressions.dll)",
|
||||
"System.Threading @ 8.0.1425.11118 (/app/System.Threading.dll)",
|
||||
"System.Threading.Channels @ 8.0.1425.11118 (/app/System.Threading.Channels.dll)",
|
||||
"System.Threading.Overlapped @ 8.0.1425.11118 (/app/System.Threading.Overlapped.dll)",
|
||||
"System.Threading.Tasks @ 8.0.1425.11118 (/app/System.Threading.Tasks.dll)",
|
||||
"System.Threading.Tasks.Dataflow @ 8.0.1425.11118 (/app/System.Threading.Tasks.Dataflow.dll)",
|
||||
"System.Threading.Tasks.Extensions @ 8.0.1425.11118 (/app/System.Threading.Tasks.Extensions.dll)",
|
||||
"System.Threading.Tasks.Parallel @ 8.0.1425.11118 (/app/System.Threading.Tasks.Parallel.dll)",
|
||||
"System.Threading.Thread @ 8.0.1425.11118 (/app/System.Threading.Thread.dll)",
|
||||
"System.Threading.ThreadPool @ 8.0.1425.11118 (/app/System.Threading.ThreadPool.dll)",
|
||||
"System.Threading.Timer @ 8.0.1425.11118 (/app/System.Threading.Timer.dll)",
|
||||
"System.Transactions @ 8.0.1425.11118 (/app/System.Transactions.dll)",
|
||||
"System.Transactions.Local @ 8.0.1425.11118 (/app/System.Transactions.Local.dll)",
|
||||
"System.ValueTuple @ 8.0.1425.11118 (/app/System.ValueTuple.dll)",
|
||||
"System.Web @ 8.0.1425.11118 (/app/System.Web.dll)",
|
||||
"System.Web.HttpUtility @ 8.0.1425.11118 (/app/System.Web.HttpUtility.dll)",
|
||||
"System.Windows @ 8.0.1425.11118 (/app/System.Windows.dll)",
|
||||
"System.Xml @ 8.0.1425.11118 (/app/System.Xml.dll)",
|
||||
"System.Xml.Linq @ 8.0.1425.11118 (/app/System.Xml.Linq.dll)",
|
||||
"System.Xml.ReaderWriter @ 8.0.1425.11118 (/app/System.Xml.ReaderWriter.dll)",
|
||||
"System.Xml.Serialization @ 8.0.1425.11118 (/app/System.Xml.Serialization.dll)",
|
||||
"System.Xml.XDocument @ 8.0.1425.11118 (/app/System.Xml.XDocument.dll)",
|
||||
"System.Xml.XPath @ 8.0.1425.11118 (/app/System.Xml.XPath.dll)",
|
||||
"System.Xml.XPath.XDocument @ 8.0.1425.11118 (/app/System.Xml.XPath.XDocument.dll)",
|
||||
"System.Xml.XmlDocument @ 8.0.1425.11118 (/app/System.Xml.XmlDocument.dll)",
|
||||
"System.Xml.XmlSerializer @ 8.0.1425.11118 (/app/System.Xml.XmlSerializer.dll)",
|
||||
"WindowsBase @ 8.0.1425.11118 (/app/WindowsBase.dll)",
|
||||
"dotnetapp @ 1.0.0.0 (/app/dotnetapp.dll)",
|
||||
"mscorlib @ 8.0.1425.11118 (/app/mscorlib.dll)",
|
||||
"netstandard @ 8.0.1425.11118 (/app/netstandard.dll)",
|
||||
)
|
||||
|
||||
var net8AppExpectedBinarySelfContainedPkgs []string
|
||||
net8AppExpectedBinarySelfContainedPkgs = append(net8AppExpectedBinarySelfContainedPkgs, net8AppBinaryOnlyPkgs...)
|
||||
net8AppExpectedBinarySelfContainedPkgs = append(net8AppExpectedBinarySelfContainedPkgs,
|
||||
@ -1197,56 +1022,6 @@ func Test_corruptDotnetPE(t *testing.T) {
|
||||
TestCataloger(t, NewDotnetPortableExecutableCataloger())
|
||||
}
|
||||
|
||||
func Test_extractVersion(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
input: "1, 0, 0, 0",
|
||||
expected: "1, 0, 0, 0",
|
||||
},
|
||||
{
|
||||
input: "Release 73",
|
||||
expected: "Release 73",
|
||||
},
|
||||
{
|
||||
input: "4.7.4076.0 built by: NET472REL1LAST_B",
|
||||
expected: "4.7.4076.0",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.input, func(t *testing.T) {
|
||||
got := extractVersionFromResourcesValue(test.input)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_spaceNormalize(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
expected: "some spaces apart",
|
||||
input: " some spaces\n\t\t \n\rapart\n",
|
||||
},
|
||||
{
|
||||
expected: "söme ¡nvalid characters",
|
||||
input: "\rsöme \u0001¡nvalid\t characters\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.expected, func(t *testing.T) {
|
||||
got := spaceNormalize(test.input)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_corruptDotnetDeps(t *testing.T) {
|
||||
pkgtest.NewCatalogTester().
|
||||
FromDirectory(t, "test-fixtures/glob-paths/src").
|
||||
@ -1604,6 +1379,7 @@ func TestParseDotnetDeps(t *testing.T) {
|
||||
}
|
||||
|
||||
func extractMatchingPackage(t *testing.T, name string, pkgs []pkg.Package) pkg.Package {
|
||||
t.Helper()
|
||||
for _, p := range pkgs {
|
||||
if p.Name == name {
|
||||
return p
|
||||
|
||||
@ -327,3 +327,53 @@ func Test_NewDotnetBinaryPackage(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_extractVersion(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
input: "1, 0, 0, 0",
|
||||
expected: "1, 0, 0, 0",
|
||||
},
|
||||
{
|
||||
input: "Release 73",
|
||||
expected: "Release 73",
|
||||
},
|
||||
{
|
||||
input: "4.7.4076.0 built by: NET472REL1LAST_B",
|
||||
expected: "4.7.4076.0",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.input, func(t *testing.T) {
|
||||
got := extractVersionFromResourcesValue(test.input)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_spaceNormalize(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
expected: "some spaces apart",
|
||||
input: " some spaces\n\t\t \n\rapart\n",
|
||||
},
|
||||
{
|
||||
expected: "söme ¡nvalid characters",
|
||||
input: "\rsöme \u0001¡nvalid\t characters\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.expected, func(t *testing.T) {
|
||||
got := spaceNormalize(test.input)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
98
syft/pkg/cataloger/internal/cpegenerate/dotnet.go
Normal file
98
syft/pkg/cataloger/internal/cpegenerate/dotnet.go
Normal file
@ -0,0 +1,98 @@
|
||||
package cpegenerate
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func candidateProductsForDotnet(p pkg.Package) fieldCandidateSet {
|
||||
products := newFieldCandidateSet()
|
||||
|
||||
switch m := p.Metadata.(type) {
|
||||
case pkg.DotnetDepsEntry:
|
||||
products.add(dotnetProductVariants(m.Name)...)
|
||||
for _, pe := range m.Executables {
|
||||
if pe.ProductName == "" {
|
||||
continue
|
||||
}
|
||||
products.add(dotnetProductVariants(pe.ProductName)...)
|
||||
}
|
||||
case pkg.DotnetPortableExecutableEntry:
|
||||
if m.ProductName != "" {
|
||||
products.add(dotnetProductVariants(m.ProductName)...)
|
||||
}
|
||||
case pkg.DotnetPackagesLockEntry:
|
||||
products.add(dotnetProductVariants(m.Name)...)
|
||||
}
|
||||
|
||||
return products
|
||||
}
|
||||
|
||||
func dotnetProductVariants(names ...string) []fieldCandidate {
|
||||
var variants []fieldCandidate
|
||||
for _, suff := range []string{"", "_.net"} {
|
||||
for _, name := range names {
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
if suff != "" && strings.HasSuffix(name, suff) {
|
||||
continue
|
||||
}
|
||||
variants = append(variants, fieldCandidate{
|
||||
value: normalizeDotnetReference(name) + suff,
|
||||
disallowSubSelections: true,
|
||||
disallowDelimiterVariations: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
return variants
|
||||
}
|
||||
|
||||
func normalizeDotnetReference(name string) string {
|
||||
name = strings.TrimSpace(strings.ToLower(name))
|
||||
name = strings.TrimSuffix(name, ".dll")
|
||||
name = strings.ReplaceAll(name, "-", "_")
|
||||
name = strings.ReplaceAll(name, " ", "_")
|
||||
name = strings.ReplaceAll(name, ".", "_")
|
||||
return name
|
||||
}
|
||||
|
||||
func candidateVendorsForDotnet(p pkg.Package) fieldCandidateSet {
|
||||
vendors := newFieldCandidateSet()
|
||||
|
||||
switch m := p.Metadata.(type) {
|
||||
case pkg.DotnetDepsEntry:
|
||||
vendors.add(fieldCandidate{
|
||||
value: normalizeDotnetReference(m.Name),
|
||||
disallowSubSelections: true,
|
||||
disallowDelimiterVariations: true,
|
||||
})
|
||||
for _, pe := range m.Executables {
|
||||
if pe.CompanyName == "" {
|
||||
continue
|
||||
}
|
||||
vendors.add(fieldCandidate{
|
||||
value: normalizeDotnetReference(pe.CompanyName),
|
||||
disallowSubSelections: true,
|
||||
disallowDelimiterVariations: true,
|
||||
})
|
||||
}
|
||||
case pkg.DotnetPortableExecutableEntry:
|
||||
if m.CompanyName != "" {
|
||||
vendors.add(fieldCandidate{
|
||||
value: normalizeDotnetReference(m.CompanyName),
|
||||
disallowSubSelections: true,
|
||||
disallowDelimiterVariations: true,
|
||||
})
|
||||
}
|
||||
case pkg.DotnetPackagesLockEntry:
|
||||
vendors.add(fieldCandidate{
|
||||
value: normalizeDotnetReference(m.Name),
|
||||
disallowSubSelections: true,
|
||||
disallowDelimiterVariations: true,
|
||||
})
|
||||
}
|
||||
|
||||
return vendors
|
||||
}
|
||||
@ -186,7 +186,8 @@ func candidateVendors(p pkg.Package) []string {
|
||||
// are the elasticsearch gem, xstream jar, and rack gem... all of these cases you can find vulnerabilities
|
||||
// with CPEs where the vendor is the product name and doesn't appear to be derived from any available package
|
||||
// metadata.
|
||||
vendors := newFieldCandidateSet(candidateProducts(p)...)
|
||||
vendors := newFieldCandidateSet()
|
||||
vendors.union(candidateProductSet(p))
|
||||
|
||||
switch p.Language {
|
||||
case pkg.JavaScript:
|
||||
@ -207,7 +208,10 @@ func candidateVendors(p pkg.Package) []string {
|
||||
}
|
||||
|
||||
switch p.Metadata.(type) {
|
||||
case pkg.RpmDBEntry:
|
||||
case pkg.DotnetDepsEntry, pkg.DotnetPackagesLockEntry, pkg.DotnetPortableExecutableEntry:
|
||||
vendors.clear()
|
||||
vendors.union(candidateVendorsForDotnet(p))
|
||||
case pkg.RpmDBEntry, pkg.RpmArchive:
|
||||
vendors.union(candidateVendorsForRPM(p))
|
||||
case pkg.RubyGemspec:
|
||||
vendors.union(candidateVendorsForRuby(p))
|
||||
@ -256,18 +260,25 @@ func candidateVendors(p pkg.Package) []string {
|
||||
}
|
||||
|
||||
func candidateProducts(p pkg.Package) []string {
|
||||
return candidateProductSet(p).uniqueValues()
|
||||
}
|
||||
|
||||
func candidateProductSet(p pkg.Package) fieldCandidateSet {
|
||||
products := newFieldCandidateSet(p.Name)
|
||||
|
||||
_, hasJavaMetadata := p.Metadata.(pkg.JavaArchive)
|
||||
|
||||
switch {
|
||||
case p.Language == pkg.Python:
|
||||
case p.Language == pkg.Dotnet || p.Type == pkg.DotnetPkg:
|
||||
products.clear()
|
||||
products.union(candidateProductsForDotnet(p))
|
||||
case p.Language == pkg.Python || p.Type == pkg.PythonPkg:
|
||||
if !strings.HasPrefix(p.Name, "python") {
|
||||
products.addValue("python-" + p.Name)
|
||||
}
|
||||
case p.Language == pkg.Java || hasJavaMetadata:
|
||||
case p.Language == pkg.Java || hasJavaMetadata || p.Type == pkg.JavaPkg:
|
||||
products.addValue(candidateProductsForJava(p)...)
|
||||
case p.Language == pkg.Go:
|
||||
case p.Language == pkg.Go || p.Type == pkg.GoModulePkg:
|
||||
// replace all candidates with only the golang-specific helper
|
||||
products.clear()
|
||||
|
||||
@ -277,11 +288,10 @@ func candidateProducts(p pkg.Package) []string {
|
||||
}
|
||||
}
|
||||
|
||||
if _, hasAPKMetadata := p.Metadata.(pkg.ApkDBEntry); hasAPKMetadata {
|
||||
switch p.Metadata.(type) {
|
||||
case pkg.ApkDBEntry:
|
||||
products.union(candidateProductsForAPK(p))
|
||||
}
|
||||
|
||||
if _, hasWordpressMetadata := p.Metadata.(pkg.WordpressPluginEntry); hasWordpressMetadata {
|
||||
case pkg.WordpressPluginEntry:
|
||||
products.clear()
|
||||
products.union(candidateProductsForWordpressPlugin(p))
|
||||
}
|
||||
@ -299,7 +309,7 @@ func candidateProducts(p pkg.Package) []string {
|
||||
// remove known candidate removals
|
||||
products.removeByValue(findProductsToRemove(defaultCandidateRemovals, p.Type, p.Name)...)
|
||||
|
||||
return products.uniqueValues()
|
||||
return products
|
||||
}
|
||||
|
||||
func addAllSubSelections(fields fieldCandidateSet) {
|
||||
|
||||
@ -308,6 +308,23 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
||||
"cpe:2.3:a:apache:cxf_rt_bindings_xml:3.3.10:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "rpm archive vendor selection",
|
||||
p: pkg.Package{
|
||||
Name: "name",
|
||||
Version: "3.2",
|
||||
FoundBy: "some-analyzer",
|
||||
Type: pkg.RpmPkg,
|
||||
Metadata: pkg.RpmArchive{
|
||||
Vendor: "some-vendor",
|
||||
},
|
||||
},
|
||||
expected: []string{
|
||||
"cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:some-vendor:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:some_vendor:name:3.2:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "rpm vendor selection",
|
||||
p: pkg.Package{
|
||||
@ -760,6 +777,75 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
||||
"cpe:2.3:a:wow_estore:wp_coder:2.5.1:*:*:*:*:wordpress:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dotnet deps.json",
|
||||
p: pkg.Package{
|
||||
Name: "Something",
|
||||
Version: "2.5.1",
|
||||
Type: pkg.DotnetPkg,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "Something-Else",
|
||||
|
||||
Executables: map[string]pkg.DotnetPortableExecutableEntry{
|
||||
"1": {
|
||||
AssemblyVersion: "assembly-version!",
|
||||
LegalCopyright: "copyright!",
|
||||
Comments: "comments!",
|
||||
InternalName: "internal!",
|
||||
CompanyName: "company!",
|
||||
ProductName: "product!",
|
||||
ProductVersion: "version!",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: []string{
|
||||
"cpe:2.3:a:company\\!:product\\!:2.5.1:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:company\\!:product\\!_.net:2.5.1:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:company\\!:something_else:2.5.1:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:company\\!:something_else_.net:2.5.1:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:something_else:product\\!:2.5.1:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:something_else:product\\!_.net:2.5.1:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:something_else:something_else:2.5.1:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:something_else:something_else_.net:2.5.1:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dotnet executable",
|
||||
p: pkg.Package{
|
||||
Name: "Something",
|
||||
Version: "2.5.1",
|
||||
Type: pkg.DotnetPkg,
|
||||
Metadata: pkg.DotnetPortableExecutableEntry{
|
||||
AssemblyVersion: "assembly-version!",
|
||||
LegalCopyright: "copyright!",
|
||||
Comments: "comments!",
|
||||
InternalName: "internal!",
|
||||
CompanyName: "company!",
|
||||
ProductName: "product!",
|
||||
ProductVersion: "version!",
|
||||
},
|
||||
},
|
||||
expected: []string{
|
||||
"cpe:2.3:a:company\\!:product\\!:2.5.1:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:company\\!:product\\!_.net:2.5.1:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dotnet package.lock",
|
||||
p: pkg.Package{
|
||||
Name: "Something",
|
||||
Version: "2.5.1",
|
||||
Type: pkg.DotnetPkg,
|
||||
Metadata: pkg.DotnetPackagesLockEntry{
|
||||
Name: "Something-Else",
|
||||
},
|
||||
},
|
||||
expected: []string{
|
||||
"cpe:2.3:a:something_else:something_else:2.5.1:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:something_else:something_else_.net:2.5.1:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
@ -937,12 +1023,12 @@ func TestCandidateVendor(t *testing.T) {
|
||||
Name: "Django",
|
||||
Type: pkg.PythonPkg,
|
||||
},
|
||||
expected: []string{"djangoproject" /* <-- known good names | default guess --> */, "Django"},
|
||||
expected: []string{"djangoproject", "python-Django", "python_Django" /* <-- known good names | default guess --> */, "python", "Django"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(fmt.Sprintf("%+v %+v", test.p, test.expected), func(t *testing.T) {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
assert.ElementsMatch(t, test.expected, candidateVendors(test.p))
|
||||
})
|
||||
}
|
||||
|
||||
@ -3,18 +3,23 @@ package cpegenerate
|
||||
import "github.com/anchore/syft/syft/pkg"
|
||||
|
||||
func candidateVendorsForRPM(p pkg.Package) fieldCandidateSet {
|
||||
metadata, ok := p.Metadata.(pkg.RpmDBEntry)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
vendors := newFieldCandidateSet()
|
||||
|
||||
if metadata.Vendor != "" {
|
||||
vendors.add(fieldCandidate{
|
||||
value: normalizeName(metadata.Vendor),
|
||||
disallowSubSelections: true,
|
||||
})
|
||||
switch m := p.Metadata.(type) {
|
||||
case pkg.RpmDBEntry:
|
||||
if m.Vendor != "" {
|
||||
vendors.add(fieldCandidate{
|
||||
value: normalizeName(m.Vendor),
|
||||
disallowSubSelections: true,
|
||||
})
|
||||
}
|
||||
case pkg.RpmArchive:
|
||||
if m.Vendor != "" {
|
||||
vendors.add(fieldCandidate{
|
||||
value: normalizeName(m.Vendor),
|
||||
disallowSubSelections: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return vendors
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user