Return a list of affected purls and the fixed package found in the ``affected_package`` AffectedPackage disregarding any ranges. Only exact version constraints (ie with an equality) are considered For eg: >>> purl = {"type": "turtle", "name": "green"} >>> vers = "vers:npm/<
(affected_package: AffectedPackage)
| 85 | |
| 86 | |
| 87 | def get_exact_purls(affected_package: AffectedPackage) -> Tuple[List[PackageURL], PackageURL]: |
| 88 | """ |
| 89 | Return a list of affected purls and the fixed package found in the ``affected_package`` |
| 90 | AffectedPackage disregarding any ranges. |
| 91 | |
| 92 | Only exact version constraints (ie with an equality) are considered |
| 93 | For eg: |
| 94 | >>> purl = {"type": "turtle", "name": "green"} |
| 95 | >>> vers = "vers:npm/<1.0.0 | >=2.0.0 | <3.0.0" |
| 96 | >>> affected_package = AffectedPackage.from_dict({ |
| 97 | ... "package": purl, |
| 98 | ... "affected_version_range": vers, |
| 99 | ... "fixed_version": "5.0.0" |
| 100 | ... }) |
| 101 | >>> got = get_exact_purls(affected_package) |
| 102 | >>> expected = ( |
| 103 | ... [PackageURL(type='turtle', namespace=None, name='green', version='2.0.0', qualifiers={}, subpath=None)], |
| 104 | ... [PackageURL(type='turtle', namespace=None, name='green', version='5.0.0', qualifiers={}, subpath=None)] |
| 105 | ... ) |
| 106 | >>> assert expected == got |
| 107 | """ |
| 108 | if not affected_package: |
| 109 | return [], [] |
| 110 | |
| 111 | try: |
| 112 | vr = affected_package.affected_version_range |
| 113 | # We need ``if c`` below because univers returns None as version |
| 114 | # in case of vers:nginx/* |
| 115 | # TODO: Revisit after https://github.com/nexB/univers/issues/33 |
| 116 | affected_purls = [] |
| 117 | fixed_versions = [] |
| 118 | if vr: |
| 119 | range_versions = [c.version for c in vr.constraints if c] |
| 120 | # Any version that's not affected by a vulnerability is considered |
| 121 | # fixed. |
| 122 | fixed_versions = [c.version for c in vr.constraints if c and c.comparator == "!="] |
| 123 | resolved_versions = [v for v in range_versions if v and v in vr] |
| 124 | for version in resolved_versions: |
| 125 | affected_purl = update_purl_version( |
| 126 | purl=affected_package.package, version=str(version) |
| 127 | ) |
| 128 | affected_purls.append(affected_purl) |
| 129 | |
| 130 | if affected_package.fixed_version: |
| 131 | fixed_versions.append(affected_package.fixed_version) |
| 132 | |
| 133 | fixed_purls = [ |
| 134 | update_purl_version(purl=affected_package.package, version=str(version)) |
| 135 | for version in fixed_versions |
| 136 | ] |
| 137 | return affected_purls, fixed_purls |
| 138 | except Exception as e: |
| 139 | logger.error(f"Failed to get exact purls for: {affected_package!r} with error: {e!r}") |
| 140 | return [], [] |
| 141 | |
| 142 | |
| 143 | class DefaultImporter(DefaultImprover): |
no test coverage detected