diff --git a/core/src/main/java/eu/fasten/core/data/metadatadb/MetadataDao.java b/core/src/main/java/eu/fasten/core/data/metadatadb/MetadataDao.java index 22cf69697..e1ca68b50 100644 --- a/core/src/main/java/eu/fasten/core/data/metadatadb/MetadataDao.java +++ b/core/src/main/java/eu/fasten/core/data/metadatadb/MetadataDao.java @@ -22,9 +22,9 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import eu.fasten.core.data.Constants; -import eu.fasten.core.data.FastenPythonURI; -import eu.fasten.core.data.FastenJavaURI; import eu.fasten.core.data.FastenCURI; +import eu.fasten.core.data.FastenJavaURI; +import eu.fasten.core.data.FastenPythonURI; import eu.fasten.core.data.FastenURI; import eu.fasten.core.data.metadatadb.codegen.Keys; import eu.fasten.core.data.metadatadb.codegen.enums.Access; @@ -74,6 +74,7 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -1587,36 +1588,45 @@ public String getArtifactName(long packageVersionId) { return result.value1() + Constants.mvnCoordinateSeparator + result.value2(); } + /** + * Finds a set of vulnerable package version ID given a set of package version IDs. + * If none of given package version IDs are vulnerable, it returns an empty set. + */ public Set findVulnerablePackageVersions(Set packageVersionIDs) { var result = context .select(PackageVersions.PACKAGE_VERSIONS.ID) - .from(PackageVersions.PACKAGE_VERSIONS) + .from(PackageVersions.PACKAGE_VERSIONS, VulnerabilitiesXPackageVersions.VULNERABILITIES_X_PACKAGE_VERSIONS) .where(PackageVersions.PACKAGE_VERSIONS.ID.in(packageVersionIDs)) - .and("package_versions.metadata::jsonb->'vulnerabilities' is not null") + .and(PackageVersions.PACKAGE_VERSIONS.ID.eq(VulnerabilitiesXPackageVersions.VULNERABILITIES_X_PACKAGE_VERSIONS.PACKAGE_VERSION_ID)) .fetch(); return new HashSet<>(result.map(Record1::value1)); } - public Map findVulnerableCallables(Set vulnerablePackageVersions, Set callableIDs) { - - PackageVersions pv = PackageVersions.PACKAGE_VERSIONS; - Modules m = Modules.MODULES; - Callables c = Callables.CALLABLES; + /** + * Given a set of vulnerable package version IDs and a set of callable IDs, it returns a map of vulnerable callable IDs + * and their corresponding vulnerability JSON statement (if any). + */ + public Map> findVulnerableCallables(Set vulnerablePackageVersions, Set callableIDs) { - var result = context - .select(c.ID, c.METADATA) - .from(c) - .join(m) - .on(c.MODULE_ID.eq(m.ID)) - .join(pv) - .on(m.PACKAGE_VERSION_ID.eq(pv.ID)) - .where(pv.ID.in(vulnerablePackageVersions)) - .and(c.ID.in(callableIDs)) - .and("callables.metadata::jsonb->'vulnerabilities' is not null") + Vulnerabilities v = Vulnerabilities.VULNERABILITIES; + VulnerabilitiesXPackageVersions vxp = VulnerabilitiesXPackageVersions.VULNERABILITIES_X_PACKAGE_VERSIONS; + VulnerabilitiesXCallables vxc = VulnerabilitiesXCallables.VULNERABILITIES_X_CALLABLES; + + var result = context. + select(vxc.CALLABLE_ID, v.STATEMENT) + .from(v, vxp, vxc) + .where(vxp.PACKAGE_VERSION_ID.in(vulnerablePackageVersions)) + .and(v.ID.eq(vxp.VULNERABILITY_ID)) + .and(vxc.CALLABLE_ID.in(callableIDs)) .fetch(); - var map = new HashMap(result.size()); + + var map = new HashMap>(result.size()); for (var record : result) { - map.put(record.value1(), new JSONObject(record.value2().data()).getJSONObject("vulnerabilities")); + if (!map.containsKey(record.value1())) { + map.put(record.value1(), new ArrayList<>(Collections.singletonList(new JSONObject(record.value2().data())))); + } else { + map.get(record.value1()).add(new JSONObject(record.value2().data())); + } } return map; }