mirror of
https://github.com/anchore/syft
synced 2024-11-10 06:14:16 +00:00
[wip]
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
parent
d6604adaaf
commit
3e21379492
3 changed files with 178 additions and 15 deletions
|
@ -69,13 +69,16 @@ func buildDotNetPackage(versionResources map[string]string, f file.LocationReadC
|
|||
}
|
||||
|
||||
metadata := pkg.DotnetPortableExecutableEntry{
|
||||
AssemblyVersion: versionResources["Assembly Version"],
|
||||
LegalCopyright: versionResources["LegalCopyright"],
|
||||
Comments: versionResources["Comments"],
|
||||
InternalName: versionResources["InternalName"],
|
||||
CompanyName: versionResources["CompanyName"],
|
||||
ProductName: versionResources["ProductName"],
|
||||
ProductVersion: versionResources["ProductVersion"],
|
||||
AssemblyVersion: versionResources["Assembly Version"],
|
||||
LegalCopyright: versionResources["LegalCopyright"],
|
||||
Comments: versionResources["Comments"],
|
||||
InternalName: versionResources["InternalName"],
|
||||
CompanyName: versionResources["CompanyName"],
|
||||
ProductName: versionResources["ProductName"],
|
||||
ProductVersion: versionResources["ProductVersion"],
|
||||
FileDescription: versionResources["FileDescription"],
|
||||
FileVersion: versionResources["FileVersion"],
|
||||
OriginalFilename: versionResources["OriginalFilename"],
|
||||
}
|
||||
|
||||
dnpkg = pkg.Package{
|
||||
|
@ -215,7 +218,7 @@ func findName(versionResources map[string]string) string {
|
|||
}
|
||||
|
||||
for _, field := range nameFields {
|
||||
value := spaceNormalize(versionResources[field])
|
||||
value := resolveValue(versionResources[field], versionResources, nil)
|
||||
if value == "" {
|
||||
continue
|
||||
}
|
||||
|
@ -225,6 +228,40 @@ func findName(versionResources map[string]string) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func resolveValue(value string, collection map[string]string, visited map[string]bool) string {
|
||||
value = spaceNormalize(value)
|
||||
|
||||
if value == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
if visited == nil {
|
||||
visited = make(map[string]bool)
|
||||
}
|
||||
|
||||
if visited[value] {
|
||||
return value
|
||||
}
|
||||
visited[value] = true
|
||||
|
||||
hasIndirect, nextKey := hasIndirectFieldPrefix(value)
|
||||
if !hasIndirect {
|
||||
return value
|
||||
}
|
||||
|
||||
return resolveValue(collection[nextKey], collection, visited)
|
||||
}
|
||||
|
||||
func hasIndirectFieldPrefix(value string) (bool, string) {
|
||||
for _, prefix := range []string{"f#", "p("} {
|
||||
cleanValue := strings.TrimPrefix(value, prefix)
|
||||
if cleanValue != value {
|
||||
return true, cleanValue
|
||||
}
|
||||
}
|
||||
return false, value
|
||||
}
|
||||
|
||||
// normalizes a string to a trimmed version with all contigous whitespace collapsed to a single space character
|
||||
func spaceNormalize(value string) string {
|
||||
value = strings.TrimSpace(value)
|
||||
|
|
|
@ -346,3 +346,126 @@ func Test_spaceNormalize(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_resolveValue(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
value string
|
||||
collection map[string]string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "simple value",
|
||||
value: "value",
|
||||
collection: map[string]string{
|
||||
"key": "value",
|
||||
},
|
||||
want: "value",
|
||||
},
|
||||
{
|
||||
name: "simple value with spaces",
|
||||
value: " value ",
|
||||
collection: map[string]string{
|
||||
"key": "value",
|
||||
},
|
||||
want: "value",
|
||||
},
|
||||
{
|
||||
name: "indirect value - f#",
|
||||
value: "f#other",
|
||||
collection: map[string]string{
|
||||
"key": "f#other",
|
||||
"other": "value",
|
||||
},
|
||||
want: "value",
|
||||
},
|
||||
{
|
||||
name: "indirect value - p(",
|
||||
value: "f#other",
|
||||
collection: map[string]string{
|
||||
"key": "p(other",
|
||||
"other": "value",
|
||||
},
|
||||
want: "value",
|
||||
},
|
||||
{
|
||||
name: "indirect value with cycles",
|
||||
value: "f#other",
|
||||
collection: map[string]string{
|
||||
"key": "f#other",
|
||||
"other": "f#key",
|
||||
},
|
||||
want: "f#other", // this is NOT ideal, but there is no "good" answer here
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, resolveValue(tt.value, tt.collection, nil))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_findVersion(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
versionResources map[string]string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "prefer file version over product version (when both semver)",
|
||||
versionResources: map[string]string{
|
||||
"FileVersion": "1.2.3",
|
||||
"ProductVersion": "4.5.6",
|
||||
},
|
||||
want: "4.5.6",
|
||||
},
|
||||
{
|
||||
name: "prefer file version over product version (when both semver)",
|
||||
versionResources: map[string]string{
|
||||
"FileVersion": "1.2.3",
|
||||
"ProductVersion": "4.5.6.7",
|
||||
},
|
||||
want: "1.2.3",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, findVersion(tt.versionResources))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_keepGreaterSemanticVersion(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
productVersion string
|
||||
fileVersion string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "product semver is greater",
|
||||
productVersion: "3.0.0",
|
||||
fileVersion: "2.0.0",
|
||||
want: "3.0.0",
|
||||
},
|
||||
{
|
||||
name: "file semver is greater",
|
||||
productVersion: "2.0.0",
|
||||
fileVersion: "3.0.0",
|
||||
want: "3.0.0",
|
||||
},
|
||||
{
|
||||
name: "semver preferred over non-semver",
|
||||
productVersion: "3.0.0.2",
|
||||
fileVersion: "3.0.0",
|
||||
want: "3.0.0",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, keepGreaterSemanticVersion(tt.productVersion, tt.fileVersion))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,11 +11,14 @@ type DotnetDepsEntry struct {
|
|||
|
||||
// DotnetPortableExecutableEntry is a struct that represents a single entry found within "VersionResources" section of a .NET Portable Executable binary file.
|
||||
type DotnetPortableExecutableEntry struct {
|
||||
AssemblyVersion string `json:"assemblyVersion"`
|
||||
LegalCopyright string `json:"legalCopyright"`
|
||||
Comments string `json:"comments,omitempty"`
|
||||
InternalName string `json:"internalName,omitempty"`
|
||||
CompanyName string `json:"companyName"`
|
||||
ProductName string `json:"productName"`
|
||||
ProductVersion string `json:"productVersion"`
|
||||
AssemblyVersion string `json:"assemblyVersion"`
|
||||
LegalCopyright string `json:"legalCopyright"`
|
||||
Comments string `json:"comments,omitempty"`
|
||||
InternalName string `json:"internalName,omitempty"`
|
||||
CompanyName string `json:"companyName"`
|
||||
ProductName string `json:"productName"`
|
||||
ProductVersion string `json:"productVersion"`
|
||||
FileVersion string `json:"fileVersion,omitempty"`
|
||||
FileDescription string `json:"fileDescription,omitempty"`
|
||||
OriginalFilename string `json:"originalFilename,omitempty"`
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue