Skip to content

Commit

Permalink
Fix panic in pom parsing (#2064)
Browse files Browse the repository at this point in the history
A recent update to gopom changed many fields to be omitted when empty,
resulting in a number of nil pointers inside the nested structure of the
pom that previously didn't exist. Defend against these in the search for
the property value.

Signed-off-by: Will Murphy <will.murphy@anchore.com>
  • Loading branch information
willmurphyscode authored Aug 25, 2023
1 parent faa9022 commit d08e2be
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
14 changes: 12 additions & 2 deletions syft/pkg/cataloger/java/parse_pom_xml.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func resolveProperty(pom gopom.Project, property *string, propertyName string) s
propertyCase := safeString(property)
log.WithFields("existingPropertyValue", propertyCase, "propertyName", propertyName).Trace("resolving property")
return propertyMatcher.ReplaceAllStringFunc(propertyCase, func(match string) string {
propertyName := strings.TrimSpace(match[2 : len(match)-1])
propertyName := strings.TrimSpace(match[2 : len(match)-1]) // remove leading ${ and trailing }
entries := pomProperties(pom)
if value, ok := entries[propertyName]; ok {
return value
Expand All @@ -210,16 +210,26 @@ func resolveProperty(pom gopom.Project, property *string, propertyName string) s
for fieldNum := 0; fieldNum < pomValueType.NumField(); fieldNum++ {
f := pomValueType.Field(fieldNum)
tag := f.Tag.Get("xml")
tag = strings.TrimSuffix(tag, ",omitempty")
tag = strings.Split(tag, ",")[0]
// a segment of the property name matches the xml tag for the field,
// so we need to recurse down the nested structs or return a match
// if we're done.
if part == tag {
pomValue = pomValue.Field(fieldNum)
pomValueType = pomValue.Type()
if pomValueType.Kind() == reflect.Ptr {
// we were recursing down the nested structs, but one of the steps
// we need to take is a nil pointer, so give up and return the original match
if pomValue.IsNil() {
return match
}
pomValue = pomValue.Elem()
if !pomValue.IsZero() {
// we found a non-zero value whose tag matches this part of the property name
pomValueType = pomValue.Type()
}
}
// If this was the last part of the property name, return the value
if partNum == numParts-1 {
return fmt.Sprintf("%v", pomValue.Interface())
}
Expand Down
18 changes: 18 additions & 0 deletions syft/pkg/cataloger/java/parse_pom_xml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,24 @@ func Test_resolveProperty(t *testing.T) {
},
expected: "org.some.parent",
},
{
name: "nil pointer halts search",
property: "${project.parent.groupId}",
pom: gopom.Project{
Parent: nil,
},
expected: "${project.parent.groupId}",
},
{
name: "nil string pointer halts search",
property: "${project.parent.groupId}",
pom: gopom.Project{
Parent: &gopom.Parent{
GroupID: nil,
},
},
expected: "${project.parent.groupId}",
},
}

for _, test := range tests {
Expand Down

0 comments on commit d08e2be

Please sign in to comment.