diff --git a/syft/pkg/cataloger/java/parse_java_manifest.go b/syft/pkg/cataloger/java/parse_java_manifest.go index d00d3352feb..14a3a363e38 100644 --- a/syft/pkg/cataloger/java/parse_java_manifest.go +++ b/syft/pkg/cataloger/java/parse_java_manifest.go @@ -108,7 +108,7 @@ func parseJavaManifest(path string, reader io.Reader) (*pkg.JavaManifest, error) return &manifest, nil } -func selectName(manifest *pkg.JavaManifest, filenameObj archiveFilename) string { +func extractNameFromApacheMavenBundlePlugin(manifest *pkg.JavaManifest) string { // special case: from https://svn.apache.org/repos/asf/felix/releases/maven-bundle-plugin-1.2.0/doc/maven-bundle-plugin-bnd.html // " is assumed to be "${groupId}.${artifactId}"." // @@ -127,10 +127,17 @@ func selectName(manifest *pkg.JavaManifest, filenameObj archiveFilename) string // if manifest != nil { if strings.Contains(manifest.Main["Created-By"], "Apache Maven Bundle Plugin") { - if v := manifest.Main["Bundle-SymbolicName"]; v != "" { + if symbolicName := manifest.Main["Bundle-SymbolicName"]; symbolicName != "" { + // It is possible that `Bundle-SymbolicName` is just the groupID (like in the case of + // https://repo1.maven.org/maven2/com/google/oauth-client/google-oauth-client/1.25.0/google-oauth-client-1.25.0.jar), + // so if `Implementation-Vendor-Id` is equal to `Bundle-SymbolicName`, bail on this logic + if vendorID := manifest.Main["Implementation-Vendor-Id"]; vendorID != "" && vendorID == symbolicName { + return "" + } + // the problem with this approach is that we don't have a strong indication of the artifactId // not having a "." in it. However, by convention it is unlikely that an artifactId would have a ".". - fields := strings.Split(v, ".") + fields := strings.Split(symbolicName, ".") // grab the last field, this is the artifactId. Note: because of [3] we do not know if this value is // correct. That is, a group id of "commons-logging" may have caused BND to swap out the reference to @@ -143,6 +150,15 @@ func selectName(manifest *pkg.JavaManifest, filenameObj archiveFilename) string } } + return "" +} + +func selectName(manifest *pkg.JavaManifest, filenameObj archiveFilename) string { + name := extractNameFromApacheMavenBundlePlugin(manifest) + if name != "" { + return name + } + // the filename tends to be the next-best reference for the package name if filenameObj.name != "" { if strings.Contains(filenameObj.name, ".") { diff --git a/syft/pkg/cataloger/java/parse_java_manifest_test.go b/syft/pkg/cataloger/java/parse_java_manifest_test.go index 7779a05d9f6..1676c14e07e 100644 --- a/syft/pkg/cataloger/java/parse_java_manifest_test.go +++ b/syft/pkg/cataloger/java/parse_java_manifest_test.go @@ -209,6 +209,31 @@ func TestSelectName(t *testing.T) { archive: newJavaArchiveFilename("/something/com.atlassian.gadgets.atlassian-gadgets-api.jar"), expected: "atlassian-gadgets-api", }, + { + // example: pkg:maven/com.google.oauth-client/google-oauth-client@1.25.0 + desc: "skip Apache Maven Bundle Plugin logic if symbolic name is same as vendor id", + manifest: pkg.JavaManifest{ + Main: map[string]string{ + "Created-By": "Apache Maven Bundle Plugin", + "Bundle-DocURL": "http://www.google.com/", + "Bundle-License": "http://www.apache.org/licenses/LICENSE-2.0.txt", + "Bundle-ManifestVersion": "2", + "Bundle-Name": "Google OAuth Client Library for Java", + "Bundle-RequiredExecutionEnvironment": "JavaSE-1.6", + "Bundle-SymbolicName": "com.google.oauth-client", + "Bundle-Vendor": "Google", + "Bundle-Version": "1.25.0", + "Created-By": "Apache Maven Bundle Plugin", + "Export-Package": "com.google.api.client.auth.openidconnect;uses:=\"com.google.api.client.auth.oauth2,com.google.api.client.json,com.google.api.client.json.webtoken,com.google.api.client.util\";version=\"1.25.0\",com.google.api.client.auth.oauth;uses:=\"com.google.api.client.http,com.google.api.client.util\";version=\"1.25.0\",com.google.api.client.auth.oauth2;uses:=\"com.google.api.client.http,com.google.api.client.json,com.google.api.client.util,com.google.api.client.util.store\";version=\"1.25.0\"", + "Implementation-Title": "Google OAuth Client Library for Java", + "Implementation-Vendor": "Google", + "Implementation-Vendor-Id": "com.google.oauth-client", + "Implementation-Version": "1.25.0", + }, + }, + archive: newJavaArchiveFilename("/something/google-oauth-client-1.25.0.jar"), + expected: "google-oauth-client", + }, } for _, test := range tests {