diff --git a/syft/pkg/cataloger/java/parse_java_manifest.go b/syft/pkg/cataloger/java/parse_java_manifest.go index 592eba4aa..784b6f910 100644 --- a/syft/pkg/cataloger/java/parse_java_manifest.go +++ b/syft/pkg/cataloger/java/parse_java_manifest.go @@ -19,48 +19,60 @@ const manifestGlob = "/META-INF/MANIFEST.MF" // For more information: https://docs.oracle.com/en/java/javase/11/docs/specs/jar/jar.html#jar-manifest func parseJavaManifest(path string, reader io.Reader) (*pkg.JavaManifest, error) { var manifest pkg.JavaManifest - sections := []map[string]string{ - make(map[string]string), + var sections []map[string]string + + currentSection := func() int { + return len(sections) - 1 } - currentSection := 0 - scanner := bufio.NewScanner(reader) + var lastKey string + scanner := bufio.NewScanner(reader) + for scanner.Scan() { line := scanner.Text() // empty lines denote section separators if strings.TrimSpace(line) == "" { - currentSection++ - // we don't want to allocate a new section map that wont necessarily be used, do that once there is + // we don't want to allocate a new section map that won't necessarily be used, do that once there is // a non-empty line to process // do not process line continuations after this lastKey = "" + continue - } else if currentSection >= len(sections) { - sections = append(sections, make(map[string]string)) } if line[0] == ' ' { // this is a continuation + if lastKey == "" { return nil, fmt.Errorf("found continuation with no previous key (%s)", line) } - sections[currentSection][lastKey] += strings.TrimSpace(line) - } else { - // this is a new key-value pair - idx := strings.Index(line, ":") - if idx == -1 { - return nil, fmt.Errorf("unable to split java manifest key-value pairs: %q", line) - } - key := strings.TrimSpace(line[0:idx]) - value := strings.TrimSpace(line[idx+1:]) - sections[currentSection][key] = value + sections[currentSection()][lastKey] += strings.TrimSpace(line) - // keep track of key for potential future continuations - lastKey = key + continue } + + if lastKey == "" { + // we're entering a new section + + sections = append(sections, make(map[string]string)) + } + + // this is a new key-value pair + idx := strings.Index(line, ":") + if idx == -1 { + return nil, fmt.Errorf("unable to split java manifest key-value pairs: %q", line) + } + + key := strings.TrimSpace(line[0:idx]) + value := strings.TrimSpace(line[idx+1:]) + + sections[currentSection()][key] = value + + // keep track of key for potential future continuations + lastKey = key } if err := scanner.Err(); err != nil { @@ -75,7 +87,7 @@ func parseJavaManifest(path string, reader io.Reader) (*pkg.JavaManifest, error) name, ok := s["Name"] if !ok { // per the manifest spec (https://docs.oracle.com/en/java/javase/11/docs/specs/jar/jar.html#jar-manifest) - // this should never happen. If it does we want to know about it, but not necessarily stop + // this should never happen. If it does, we want to know about it, but not necessarily stop // cataloging entirely... for this reason we only log. log.Warnf("java manifest section found without a name: %s", path) name = strconv.Itoa(i) diff --git a/syft/pkg/cataloger/java/parse_java_manifest_test.go b/syft/pkg/cataloger/java/parse_java_manifest_test.go index a67736c93..e36cc2b13 100644 --- a/syft/pkg/cataloger/java/parse_java_manifest_test.go +++ b/syft/pkg/cataloger/java/parse_java_manifest_test.go @@ -58,6 +58,21 @@ func TestParseJavaManifest(t *testing.T) { }, }, }, + { + fixture: "test-fixtures/manifest/extra-empty-lines", + expected: pkg.JavaManifest{ + Main: map[string]string{ + "Manifest-Version": "1.0", + "Archiver-Version": "Plexus Archiver", + "Created-By": "Apache Maven 3.6.3", + }, + NamedSections: map[string]map[string]string{ + "thing-1": { + "Built-By": "?", + }, + }, + }, + }, { fixture: "test-fixtures/manifest/continuation", expected: pkg.JavaManifest{ diff --git a/syft/pkg/cataloger/java/test-fixtures/manifest/extra-empty-lines b/syft/pkg/cataloger/java/test-fixtures/manifest/extra-empty-lines new file mode 100644 index 000000000..5c68a7d7b --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/manifest/extra-empty-lines @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Archiver-Version: Plexus Archiver +Created-By: Apache Maven 3.6.3 + + +Name: thing-1 +Built-By: ?