diff --git a/vulnerabilities/templates/package_details.html b/vulnerabilities/templates/package_details.html
index 75e006839..26de42fa8 100644
--- a/vulnerabilities/templates/package_details.html
+++ b/vulnerabilities/templates/package_details.html
@@ -2,6 +2,7 @@
{% load humanize %}
{% load widget_tweaks %}
{% load static %}
+{% load url_filters %}
{% block title %}
VulnerableCode Package Details - {{ package.purl }}
@@ -91,7 +92,7 @@
{% if fixed_package_details.next_non_vulnerable.version %}
- {{ fixed_package_details.next_non_vulnerable.version }}
{% else %}
None.
@@ -104,7 +105,7 @@
|
{% if fixed_package_details.latest_non_vulnerable.version %}
- {{ fixed_package_details.latest_non_vulnerable.version }}
{% else %}
None.
@@ -119,7 +120,7 @@
- Vulnerabilities affecting this package ({{ affected_by_vulnerabilities|length }})
+ Vulnerabilities affecting this package ({{ affected_by_vulnerabilities|length }})
@@ -127,7 +128,7 @@
Vulnerability |
Summary |
- Fixed by |
+ Fixed by |
@@ -160,32 +161,28 @@
{% for vuln in value %}
{% if vuln.vulnerability.vulnerability_id == vulnerability.vulnerability_id %}
{% if vuln.fixed_by_package_details is None %}
- There are no reported fixed by versions.
+ There are no reported fixed by versions.
{% else %}
{% for fixed_pkg in vuln.fixed_by_package_details %}
{% if fixed_pkg.fixed_by_purl_vulnerabilities|length == 0 %}
- {{ fixed_pkg.fixed_by_purl.version }}
- Affected
- by 0 other vulnerabilities.
+ Affected by 0 other vulnerabilities.
{% else %}
- {{ fixed_pkg.fixed_by_purl.version }}
{% if fixed_pkg.fixed_by_purl_vulnerabilities|length != 1 %}
- Affected
- by {{ fixed_pkg.fixed_by_purl_vulnerabilities|length }} other
+ Affected by {{ fixed_pkg.fixed_by_purl_vulnerabilities|length }} other
vulnerabilities.
{% else %}
- Affected
- by {{ fixed_pkg.fixed_by_purl_vulnerabilities|length }} other
+ Affected by {{ fixed_pkg.fixed_by_purl_vulnerabilities|length }} other
vulnerability.
{% endif %}
-
+
- This version is affected
- by these other vulnerabilities:
+ This version is affected by these other vulnerabilities:
{% for fixed_by_vuln in fixed_pkg.fixed_by_purl_vulnerabilities %}
@@ -226,8 +222,7 @@
{% empty %}
- This package is not known to be affected by vulnerabilities.
+ This package is not known to be affected by vulnerabilities.
|
{% endfor %}
@@ -237,7 +232,7 @@
- Vulnerabilities fixed by this package ({{ fixing_vulnerabilities|length }})
+ Vulnerabilities fixed by this package ({{ fixing_vulnerabilities|length }})
@@ -273,8 +268,7 @@
{% empty %}
- This package is not known to fix
- vulnerabilities.
+ This package is not known to fix vulnerabilities.
|
{% endfor %}
@@ -340,4 +334,4 @@
{% endif %}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/vulnerabilities/templates/packages.html b/vulnerabilities/templates/packages.html
index 2f91a5422..1f7687429 100644
--- a/vulnerabilities/templates/packages.html
+++ b/vulnerabilities/templates/packages.html
@@ -41,14 +41,14 @@
- Affected by vulnerabilities
+ Affected by vulnerabilities
- Fixing vulnerabilities
+ Fixing vulnerabilities
|
diff --git a/vulnerabilities/templates/vulnerabilities.html b/vulnerabilities/templates/vulnerabilities.html
index bdada6ee1..023d3f97f 100644
--- a/vulnerabilities/templates/vulnerabilities.html
+++ b/vulnerabilities/templates/vulnerabilities.html
@@ -32,8 +32,8 @@
Vulnerability id |
Aliases |
- Affected packages |
- Fixed by packages |
+ Affected packages |
+ Fixed by packages |
diff --git a/vulnerabilities/templates/vulnerability_details.html b/vulnerabilities/templates/vulnerability_details.html
index c950adad1..d12748d0c 100644
--- a/vulnerabilities/templates/vulnerability_details.html
+++ b/vulnerabilities/templates/vulnerability_details.html
@@ -3,6 +3,7 @@
{% load widget_tweaks %}
{% load static %}
{% load show_cvss %}
+{% load url_filters %}
{% block title %}
VulnerableCode Vulnerability Details - {{ vulnerability.vulnerability_id }}
@@ -32,17 +33,10 @@
Essentials
-
+
- Fixed by packages ({{ fixed_by_packages|length }})
-
-
-
-
-
-
- Affected packages ({{ affected_packages|length }})
+ Affected/Fixed by packages ({{ affected_packages|length }}/{{ fixed_by_packages|length }})
@@ -164,62 +158,52 @@
- Fixed by packages ({{ fixed_by_packages|length }})
+ Affected/Fixed by packages ({{ affected_packages|length }}/{{ fixed_by_packages|length }})
-
-
-
- Affected packages ({{ affected_packages|length }})
-
-
-
@@ -251,6 +235,48 @@
+
+
+
+
+ Affected |
+ Fixed by |
+
+
+
+ {% for package in affected_packages %}
+
+
+ {{ package.purl }}
+ |
+
+
+ {% for match in all_affected_fixed_by_matches %}
+ {% if match.affected_package == package %}
+ {% if match.matched_fixed_by_packages|length > 0 %}
+ {% for pkg in match.matched_fixed_by_packages %}
+ {{ pkg }}
+
+ {% endfor %}
+ {% else %}
+ There are no reported fixed by versions.
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+
+ |
+
+ {% empty %}
+
+
+ This vulnerability is not known to affect any packages.
+ |
+
+ {% endfor %}
+
+
+
+
-
-
-
-
-
- Package URL
- |
-
-
-
- {% for package in affected_packages %}
-
-
- {{ package.purl }}
- |
-
- {% empty %}
-
-
- This vulnerability is not known to affect any packages.
- |
-
- {% endfor %}
-
-
-
-
-
-
-
-
-
- Package URL
- |
-
-
-
- {% for package in fixed_by_packages %}
-
-
- {{package.purl }}
- |
-
- {% empty %}
-
-
- This vulnerability is not known to be fixed by any packages.
- |
-
- {% endfor %}
-
-
-
{% for severity_vector in severity_vectors %}
{% if severity_vector.version == '2.0' %}
@@ -455,7 +424,7 @@
{{ vulnerability.kev.get_known_ransomware_campaign_use_type }} |
-
+
{% if vulnerability.kev.description %}
@@ -479,7 +448,7 @@
| {{ vulnerability.kev.required_action }} |
{% endif %}
-
+
{% if vulnerability.kev.resources_and_notes %}
@@ -491,7 +460,7 @@
| {{ vulnerability.kev.resources_and_notes }} |
{% endif %}
-
+
{% if vulnerability.kev.due_date %}
@@ -515,12 +484,12 @@
| {{ vulnerability.kev.date_added }} |
{% endif %}
-
+
{% endif %}
-
+
{% for severity in severities %}
{% if severity.scoring_system == 'epss' %}
@@ -548,7 +517,7 @@
{{ severity.value }} |
-
+
{% if severity.published_at %}
@@ -560,7 +529,7 @@
|
{{ severity.published_at }} |
- {% endif %}
+ {% endif %}
@@ -612,6 +581,12 @@
{{log.source_url }} |
{{ log.software_version }} |
+ {% empty %}
+
+
+ There are no relevant records.
+ |
+
{% endfor %}
@@ -639,4 +614,4 @@
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/vulnerabilities/templatetags/url_filters.py b/vulnerabilities/templatetags/url_filters.py
new file mode 100644
index 000000000..a6dda1dd8
--- /dev/null
+++ b/vulnerabilities/templatetags/url_filters.py
@@ -0,0 +1,11 @@
+from urllib.parse import quote
+
+import packageurl
+from django import template
+
+register = template.Library()
+
+
+@register.filter(name="url_quote")
+def url_quote_filter(value):
+ return quote(str(value))
diff --git a/vulnerabilities/tests/test_data/package_sort/input_purls.txt b/vulnerabilities/tests/test_data/package_sort/input_purls.txt
new file mode 100644
index 000000000..9f0b214b1
--- /dev/null
+++ b/vulnerabilities/tests/test_data/package_sort/input_purls.txt
@@ -0,0 +1,103 @@
+pkg:alpm/arch/containers-common@1:0.47.4-4?arch=x86_64
+pkg:alpm/arch/pacman@6.0.1-1?arch=x86_64
+pkg:alpm/arch/python-pip@21.0-1?arch=any
+pkg:cargo/clap@3.0.0
+pkg:cargo/clap@3.0.1
+pkg:cargo/clap@3.0.10
+pkg:cargo/clap@3.0.11
+pkg:cargo/clap@3.0.2
+pkg:cargo/clap@3.0.20
+pkg:cargo/rand@0.7.2
+pkg:cargo/structopt@0.3.11
+pkg:composer/bk2k/bootstrap-package@11.0.2
+pkg:composer/bk2k/bootstrap-package@11.0.3
+pkg:composer/bk2k/bootstrap-package@7.1.0
+pkg:composer/bk2k/bootstrap-package@7.1.1
+pkg:composer/bk2k/bootstrap-package@7.1.2
+pkg:conan/capnproto@0.15.0
+pkg:conan/capnproto@0.15.2
+pkg:conan/capnproto@0.7.0
+pkg:conan/capnproto@0.8.0
+pkg:deb/debian/jackson-databind@2.12.1-1%2Bdeb11u1
+pkg:deb/debian/jackson-databind@2.12.1-1%2Bdeb11u1?distro=sid
+pkg:deb/debian/jackson-databind@2.13.2.2-1?distro=sid
+pkg:deb/debian/jackson-databind@2.13.2.2-1?distro=stretch
+pkg:deb/debian/jackson-databind@2.14.0-1?distro=sid
+pkg:deb/debian/jackson-databind@2.8.6-1%2Bdeb9u10?distro=stretch
+pkg:deb/debian/jackson-databind@2.8.6-1%2Bdeb9u7?distro=stretch
+pkg:deb/debian/jackson-databind@2.9.8-3%2Bdeb10u4?distro=sid
+pkg:deb/ubuntu/dpkg@1.13.11ubuntu7.2
+pkg:deb/ubuntu/dpkg@1.13.11ubuntu7~proposed
+pkg:deb/ubuntu/dpkg@1.13.21ubuntu1
+pkg:deb/ubuntu/dpkg@1.14.5ubuntu11
+pkg:deb/ubuntu/dpkg@1.14.5ubuntu12
+pkg:deb/ubuntu/dpkg@1.14.5ubuntu2
+pkg:deb/ubuntu/dpkg@1.14.5ubuntu3
+pkg:gem/actionpack@3.1.1
+pkg:gem/actionpack@3.1.10
+pkg:gem/actionpack@3.1.11
+pkg:gem/actionpack@3.1.2
+pkg:gem/webbynode@1.0.5.beta10
+pkg:gem/webbynode@1.0.5.beta2
+pkg:gem/webbynode@1.0.5.beta3
+pkg:generic/postgresql@10.19.0
+pkg:generic/postgresql@10.2.0
+pkg:generic/postgresql@10.21.0
+pkg:generic/postgresql@10.22.0
+pkg:generic/postgresql@10.3.0
+pkg:generic/postgresql@10.4.0
+pkg:github/istio/istio@0.2.0
+pkg:github/istio/istio@0.2.1
+pkg:github/istio/istio@0.2.10
+pkg:github/istio/istio@0.2.11
+pkg:github/istio/istio@0.2.12
+pkg:github/istio/istio@0.2.2
+pkg:golang/github.com/1Panel-dev/1Panel@1.10.1-lts
+pkg:golang/github.com/1Panel-dev/1Panel@1.10.3
+pkg:golang/github.com/1Panel-dev/1Panel@1.10.3-lts
+pkg:golang/github.com/1Panel-dev/1Panel@1.3.6
+pkg:golang/github.com/1Panel-dev/1Panel@1.4.3
+pkg:hex/pow@1.0.15
+pkg:hex/pow@1.0.16
+pkg:hex/pow@1.0.2
+pkg:hex/pow@1.0.3
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.1.1
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.10.0
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.12.6.1
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.2
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.2.1
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.2.1
+pkg:maven/io.netty/netty-codec-dns@4.1.101.Final
+pkg:maven/io.netty/netty-codec-dns@4.1.97.Final
+pkg:maven/io.netty/netty-codec-http@4.1.101.Final
+pkg:maven/io.netty/netty-codec-http@4.1.97.Final
+pkg:maven/io.netty/netty-codec-http2@4.1.101.Final
+pkg:maven/io.netty/netty-codec-http2@4.1.97.Final
+pkg:npm/%40budibase/bbui@1.2.44-alpha.1
+pkg:npm/%40budibase/bbui@1.2.44-alpha.10
+pkg:npm/%40budibase/bbui@1.2.44-alpha.11
+pkg:npm/%40budibase/bbui@1.2.44-alpha.2
+pkg:npm/%40budibase/bbui@1.2.44-alpha.3
+pkg:npm/bootstrap-select@1.13.5
+pkg:npm/bootstrap-select@1.13.6
+pkg:npm/bootstrap-select@1.6.2
+pkg:npm/bootstrap-select@1.6.3
+pkg:nuget/adplug@2.3.0-beta17
+pkg:nuget/adplug@2.3.0-beta172
+pkg:nuget/adplug@2.3.0-beta173
+pkg:nuget/adplug@2.3.0-beta18
+pkg:nuget/adplug@2.3.0-beta186
+pkg:nuget/adplug@2.3.0-beta19
+pkg:nuget/adplug@2.3.0-beta190
+pkg:pypi/jinja2@2.1
+pkg:pypi/jinja2@2.1.1
+pkg:pypi/jinja2@2.10
+pkg:pypi/jinja2@2.2
+pkg:pypi/jinja2@2.2.1
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=11
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=12
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=13
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=2
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=5
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=7
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=9
diff --git a/vulnerabilities/tests/test_data/package_sort/purls_with_excel_sort.txt b/vulnerabilities/tests/test_data/package_sort/purls_with_excel_sort.txt
new file mode 100644
index 000000000..de9405797
--- /dev/null
+++ b/vulnerabilities/tests/test_data/package_sort/purls_with_excel_sort.txt
@@ -0,0 +1,132 @@
+pkg:alpm/arch/containers-common@1:0.47.4-4?arch=x86_64
+pkg:alpm/arch/pacman@6.0.1-1?arch=x86_64
+pkg:alpm/arch/python-pip@21.0-1?arch=any
+pkg:apk/alpine/apk@2.12.9-r3?arch=x86
+pkg:apk/alpine/curl@7.83.0-r0?arch=x86
+pkg:bitbucket/birkenfeld/pygments-main@244fd47e07d1014f0aed9c
+pkg:bitnami/wordpress?distro=debian-12
+pkg:bitnami/wordpress@6.2.0?arch=arm64&distro=debian-12
+pkg:bitnami/wordpress@6.2.0?arch=arm64&distro=photon-4
+pkg:bitnami/wordpress@6.2.0?distro=debian-12
+pkg:cargo/clap@3.0.0
+pkg:cargo/clap@3.0.1
+pkg:cargo/clap@3.0.10
+pkg:cargo/clap@3.0.11
+pkg:cargo/clap@3.0.2
+pkg:cargo/clap@3.0.20
+pkg:cargo/rand@0.7.2
+pkg:cargo/structopt@0.3.11
+pkg:cocoapods/AFNetworking@4.0.1
+pkg:cocoapods/GoogleUtilities@7.5.2#NSData+zlib
+pkg:cocoapods/MapsIndoors@3.24.0
+pkg:cocoapods/ShareKit@2.0#Twitter
+pkg:composer/bk2k/bootstrap-package@11.0.2
+pkg:composer/bk2k/bootstrap-package@11.0.3
+pkg:composer/bk2k/bootstrap-package@7.1.0
+pkg:composer/bk2k/bootstrap-package@7.1.1
+pkg:composer/bk2k/bootstrap-package@7.1.2
+pkg:conan/capnproto@0.15.0
+pkg:conan/capnproto@0.15.2
+pkg:conan/capnproto@0.7.0
+pkg:conan/capnproto@0.8.0
+pkg:conda/absl-py@0.4.1?build=py36h06a4308_0&channel=main&subdir=linux-64&type=tar.bz2
+pkg:conda/openssl@1.0.2l?channel=main&subdir=linux-64&build=h077ae2c_5&type=tar.bz2
+pkg:cpan/DROLSKY/DateTime@1.55
+pkg:cpan/DROLSKY/DateTime@1.56
+pkg:cpan/DROLSKY/DateTime@1.57
+pkg:cran/caret@6.0-88
+pkg:cran/caret@6.0-89
+pkg:cran/caret@6.0-90
+pkg:deb/debian/jackson-databind@2.12.1-1%2Bdeb11u1
+pkg:deb/debian/jackson-databind@2.12.1-1%2Bdeb11u1?distro=sid
+pkg:deb/debian/jackson-databind@2.13.2.2-1?distro=sid
+pkg:deb/debian/jackson-databind@2.13.2.2-1?distro=stretch
+pkg:deb/debian/jackson-databind@2.14.0-1?distro=sid
+pkg:deb/debian/jackson-databind@2.8.6-1%2Bdeb9u10?distro=stretch
+pkg:deb/debian/jackson-databind@2.8.6-1%2Bdeb9u7?distro=stretch
+pkg:deb/debian/jackson-databind@2.9.8-3%2Bdeb10u4?distro=sid
+pkg:deb/ubuntu/dpkg@1.13.11ubuntu7.2
+pkg:deb/ubuntu/dpkg@1.13.11ubuntu7~proposed
+pkg:deb/ubuntu/dpkg@1.13.21ubuntu1
+pkg:deb/ubuntu/dpkg@1.14.5ubuntu11
+pkg:deb/ubuntu/dpkg@1.14.5ubuntu12
+pkg:deb/ubuntu/dpkg@1.14.5ubuntu2
+pkg:deb/ubuntu/dpkg@1.14.5ubuntu3
+pkg:docker/cassandra@latest
+pkg:docker/customer/dockerimage@sha256%3A244fd47e07d10?repository_url=gcr.io
+pkg:docker/smartentry/debian@dc437cc87d10
+pkg:gem/actionpack@3.1.1
+pkg:gem/actionpack@3.1.10
+pkg:gem/actionpack@3.1.11
+pkg:gem/actionpack@3.1.2
+pkg:gem/webbynode@1.0.5.beta10
+pkg:gem/webbynode@1.0.5.beta2
+pkg:gem/webbynode@1.0.5.beta3
+pkg:generic/postgresql@10.19.0
+pkg:generic/postgresql@10.2.0
+pkg:generic/postgresql@10.21.0
+pkg:generic/postgresql@10.22.0
+pkg:generic/postgresql@10.3.0
+pkg:generic/postgresql@10.4.0
+pkg:github/istio/istio@0.2.0
+pkg:github/istio/istio@0.2.1
+pkg:github/istio/istio@0.2.10
+pkg:github/istio/istio@0.2.11
+pkg:github/istio/istio@0.2.12
+pkg:github/istio/istio@0.2.2
+pkg:golang/github.com/1Panel-dev/1Panel@1.10.1-lts
+pkg:golang/github.com/1Panel-dev/1Panel@1.10.3
+pkg:golang/github.com/1Panel-dev/1Panel@1.10.3-lts
+pkg:golang/github.com/1Panel-dev/1Panel@1.3.6
+pkg:golang/github.com/1Panel-dev/1Panel@1.4.3
+pkg:hackage/Allure@0.11.0.0
+pkg:hackage/Allure@0.9.5.0
+pkg:hex/pow@1.0.15
+pkg:hex/pow@1.0.16
+pkg:hex/pow@1.0.2
+pkg:hex/pow@1.0.3
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.1.1
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.10.0
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.12.6.1
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.2
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.2.1
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.2.1
+pkg:maven/io.netty/netty-codec-dns@4.1.101.Final
+pkg:maven/io.netty/netty-codec-dns@4.1.97.Final
+pkg:maven/io.netty/netty-codec-http@4.1.101.Final
+pkg:maven/io.netty/netty-codec-http@4.1.97.Final
+pkg:maven/io.netty/netty-codec-http2@4.1.101.Final
+pkg:maven/io.netty/netty-codec-http2@4.1.97.Final
+pkg:npm/%40budibase/bbui@1.2.44-alpha.1
+pkg:npm/%40budibase/bbui@1.2.44-alpha.10
+pkg:npm/%40budibase/bbui@1.2.44-alpha.11
+pkg:npm/%40budibase/bbui@1.2.44-alpha.2
+pkg:npm/%40budibase/bbui@1.2.44-alpha.3
+pkg:npm/bootstrap-select@1.13.5
+pkg:npm/bootstrap-select@1.13.6
+pkg:npm/bootstrap-select@1.6.2
+pkg:npm/bootstrap-select@1.6.3
+pkg:nuget/adplug@2.3.0-beta17
+pkg:nuget/adplug@2.3.0-beta172
+pkg:nuget/adplug@2.3.0-beta173
+pkg:nuget/adplug@2.3.0-beta18
+pkg:nuget/adplug@2.3.0-beta186
+pkg:nuget/adplug@2.3.0-beta19
+pkg:nuget/adplug@2.3.0-beta190
+pkg:pypi/jinja2@2.1
+pkg:pypi/jinja2@2.1.1
+pkg:pypi/jinja2@2.10
+pkg:pypi/jinja2@2.2
+pkg:pypi/jinja2@2.2.1
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=11
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=12
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=13
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=2
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=5
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=7
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=9
+pkg:swid/Acme/example.com/Enterprise+Server@1.0.0?tag_id=75b8c285-fa7b-485b-b199-4745e3004d0d
+pkg:swid/Adobe+Systems+Incorporated/Adobe+InDesign@CC?tag_id=CreativeCloud-CS6-Win-GM-MUL
+pkg:swid/Fedora@29?tag_id=org.fedoraproject.Fedora-29
+pkg:swift/github.com/Alamofire/Alamofire@5.4.3
+pkg:swift/github.com/RxSwiftCommunity/RxFlow@2.12.4
diff --git a/vulnerabilities/tests/test_data/package_sort/sorted_purls.txt b/vulnerabilities/tests/test_data/package_sort/sorted_purls.txt
new file mode 100644
index 000000000..886119bfd
--- /dev/null
+++ b/vulnerabilities/tests/test_data/package_sort/sorted_purls.txt
@@ -0,0 +1,103 @@
+pkg:alpm/arch/containers-common@1:0.47.4-4?arch=x86_64
+pkg:alpm/arch/pacman@6.0.1-1?arch=x86_64
+pkg:alpm/arch/python-pip@21.0-1?arch=any
+pkg:cargo/clap@3.0.0
+pkg:cargo/clap@3.0.1
+pkg:cargo/clap@3.0.2
+pkg:cargo/clap@3.0.10
+pkg:cargo/clap@3.0.11
+pkg:cargo/clap@3.0.20
+pkg:cargo/rand@0.7.2
+pkg:cargo/structopt@0.3.11
+pkg:composer/bk2k/bootstrap-package@7.1.0
+pkg:composer/bk2k/bootstrap-package@7.1.1
+pkg:composer/bk2k/bootstrap-package@7.1.2
+pkg:composer/bk2k/bootstrap-package@11.0.2
+pkg:composer/bk2k/bootstrap-package@11.0.3
+pkg:conan/capnproto@0.7.0
+pkg:conan/capnproto@0.8.0
+pkg:conan/capnproto@0.15.0
+pkg:conan/capnproto@0.15.2
+pkg:deb/debian/jackson-databind@2.8.6-1%2Bdeb9u7?distro=stretch
+pkg:deb/debian/jackson-databind@2.8.6-1%2Bdeb9u10?distro=stretch
+pkg:deb/debian/jackson-databind@2.9.8-3%2Bdeb10u4?distro=sid
+pkg:deb/debian/jackson-databind@2.12.1-1%2Bdeb11u1
+pkg:deb/debian/jackson-databind@2.12.1-1%2Bdeb11u1?distro=sid
+pkg:deb/debian/jackson-databind@2.13.2.2-1?distro=sid
+pkg:deb/debian/jackson-databind@2.13.2.2-1?distro=stretch
+pkg:deb/debian/jackson-databind@2.14.0-1?distro=sid
+pkg:deb/ubuntu/dpkg@1.13.11ubuntu7~proposed
+pkg:deb/ubuntu/dpkg@1.13.11ubuntu7.2
+pkg:deb/ubuntu/dpkg@1.13.21ubuntu1
+pkg:deb/ubuntu/dpkg@1.14.5ubuntu2
+pkg:deb/ubuntu/dpkg@1.14.5ubuntu3
+pkg:deb/ubuntu/dpkg@1.14.5ubuntu11
+pkg:deb/ubuntu/dpkg@1.14.5ubuntu12
+pkg:gem/actionpack@3.1.1
+pkg:gem/actionpack@3.1.2
+pkg:gem/actionpack@3.1.10
+pkg:gem/actionpack@3.1.11
+pkg:gem/webbynode@1.0.5.beta2
+pkg:gem/webbynode@1.0.5.beta3
+pkg:gem/webbynode@1.0.5.beta10
+pkg:generic/postgresql@10.2.0
+pkg:generic/postgresql@10.3.0
+pkg:generic/postgresql@10.4.0
+pkg:generic/postgresql@10.19.0
+pkg:generic/postgresql@10.21.0
+pkg:generic/postgresql@10.22.0
+pkg:github/istio/istio@0.2.0
+pkg:github/istio/istio@0.2.1
+pkg:github/istio/istio@0.2.2
+pkg:github/istio/istio@0.2.10
+pkg:github/istio/istio@0.2.11
+pkg:github/istio/istio@0.2.12
+pkg:golang/github.com/1Panel-dev/1Panel@1.3.6
+pkg:golang/github.com/1Panel-dev/1Panel@1.4.3
+pkg:golang/github.com/1Panel-dev/1Panel@1.10.1-lts
+pkg:golang/github.com/1Panel-dev/1Panel@1.10.3-lts
+pkg:golang/github.com/1Panel-dev/1Panel@1.10.3
+pkg:hex/pow@1.0.2
+pkg:hex/pow@1.0.3
+pkg:hex/pow@1.0.15
+pkg:hex/pow@1.0.16
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.1.1
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.2.1
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.10.0
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.12.6.1
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.2
+pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.2.1
+pkg:maven/io.netty/netty-codec-dns@4.1.97.Final
+pkg:maven/io.netty/netty-codec-dns@4.1.101.Final
+pkg:maven/io.netty/netty-codec-http@4.1.97.Final
+pkg:maven/io.netty/netty-codec-http@4.1.101.Final
+pkg:maven/io.netty/netty-codec-http2@4.1.97.Final
+pkg:maven/io.netty/netty-codec-http2@4.1.101.Final
+pkg:npm/bootstrap-select@1.6.2
+pkg:npm/bootstrap-select@1.6.3
+pkg:npm/bootstrap-select@1.13.5
+pkg:npm/bootstrap-select@1.13.6
+pkg:npm/%40budibase/bbui@1.2.44-alpha.1
+pkg:npm/%40budibase/bbui@1.2.44-alpha.2
+pkg:npm/%40budibase/bbui@1.2.44-alpha.3
+pkg:npm/%40budibase/bbui@1.2.44-alpha.10
+pkg:npm/%40budibase/bbui@1.2.44-alpha.11
+pkg:nuget/adplug@2.3.0-beta17
+pkg:nuget/adplug@2.3.0-beta172
+pkg:nuget/adplug@2.3.0-beta173
+pkg:nuget/adplug@2.3.0-beta18
+pkg:nuget/adplug@2.3.0-beta186
+pkg:nuget/adplug@2.3.0-beta19
+pkg:nuget/adplug@2.3.0-beta190
+pkg:pypi/jinja2@2.1
+pkg:pypi/jinja2@2.1.1
+pkg:pypi/jinja2@2.2
+pkg:pypi/jinja2@2.2.1
+pkg:pypi/jinja2@2.10
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=11
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=12
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=13
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=2
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=5
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=7
+pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=9
diff --git a/vulnerabilities/tests/test_view.py b/vulnerabilities/tests/test_view.py
index 20eb880af..1ba488320 100644
--- a/vulnerabilities/tests/test_view.py
+++ b/vulnerabilities/tests/test_view.py
@@ -7,15 +7,25 @@
# See https://aboutcode.org for more information about nexB OSS projects.
#
+import os
+
+import pytest
from django.test import Client
from django.test import TestCase
from packageurl import PackageURL
+from univers import versions
from vulnerabilities.models import Alias
from vulnerabilities.models import Package
from vulnerabilities.models import Vulnerability
+from vulnerabilities.templatetags.url_filters import url_quote_filter
from vulnerabilities.views import PackageDetails
from vulnerabilities.views import PackageSearch
+from vulnerabilities.views import get_purl_version_class
+from vulnerabilities.views import purl_sort_key
+
+BASE_DIR = os.path.dirname(os.path.abspath(__file__))
+TEST_DIR = os.path.join(BASE_DIR, "test_data/package_sort")
class PackageSearchTestCase(TestCase):
@@ -176,3 +186,90 @@ def test_robots_txt(self):
assert response.status_code == 200
response = self.client.post("/robots.txt")
assert response.status_code == 405
+
+
+class TestPackageSortTestCase(TestCase):
+ def setUp(self):
+ self.client = Client()
+ TEST_DATA = os.path.join(TEST_DIR, "input_purls.txt")
+ with open(TEST_DATA) as f:
+ input_purls = [l for l in f.readlines()]
+ self.input_purls = input_purls
+ for pkg in input_purls:
+ real_purl = PackageURL.from_string(pkg)
+ attrs = {k: v for k, v in real_purl.to_dict().items() if v}
+ Package.objects.create(**attrs)
+
+ def test_sorted_queryset(self):
+ qs_all = Package.objects.all()
+ pkgs_qs_all = list(qs_all)
+ sorted_pkgs_qs_all = sorted(pkgs_qs_all, key=purl_sort_key)
+
+ pkg_package_urls = [obj.package_url for obj in sorted_pkgs_qs_all]
+ sorted_purls = os.path.join(TEST_DIR, "sorted_purls.txt")
+ with open(sorted_purls, "r") as f:
+ expected_content = f.read().splitlines()
+ assert pkg_package_urls == expected_content
+
+ def test_get_purl_version_class(self):
+ test_cases = {
+ "pkg:alpm/arch/containers-common@1:0.47.4-4?arch=x86_64": versions.ArchLinuxVersion,
+ "pkg:cargo/clap@3.0.0": versions.SemverVersion,
+ "pkg:composer/bk2k/bootstrap-package@7.1.0": versions.ComposerVersion,
+ "pkg:conan/capnproto@0.7.0": versions.ConanVersion,
+ "pkg:deb/debian/jackson-databind@2.8.6-1%2Bdeb9u7?distro=stretch": versions.DebianVersion,
+ "pkg:deb/ubuntu/dpkg@1.13.11ubuntu7~proposed": versions.DebianVersion,
+ "pkg:gem/actionpack@3.1.1": versions.RubygemsVersion,
+ "pkg:generic/postgresql@10.2.0": versions.SemverVersion,
+ "pkg:github/istio/istio@0.2.0": versions.SemverVersion,
+ "pkg:golang/github.com/1Panel-dev/1Panel@1.3.6": versions.GolangVersion,
+ "pkg:hex/pow@1.0.2": versions.SemverVersion,
+ "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.1.1": versions.MavenVersion,
+ "pkg:npm/bootstrap-select@1.6.2": versions.SemverVersion,
+ "pkg:nuget/adplug@2.3.0-beta17": versions.NugetVersion,
+ "pkg:pypi/jinja2@2.1": versions.PypiVersion,
+ "pkg:rpm/redhat/openssl@1.0.1e-30.el6_6?arch=11": versions.RpmVersion,
+ }
+ for k in test_cases:
+ pkg = Package.objects.get(package_url=k)
+ assert get_purl_version_class(pkg) == test_cases.get(k)
+
+
+class TestCustomFilters:
+ @pytest.mark.parametrize(
+ "input_value, expected_output",
+ [
+ (
+ "pkg:rpm/redhat/katello-client-bootstrap@1.1.0-2?arch=el6sat",
+ "pkg%3Arpm/redhat/katello-client-bootstrap%401.1.0-2%3Farch%3Del6sat",
+ ),
+ (
+ "pkg:alpine/nginx@1.10.3-r1?arch=armhf&distroversion=v3.5&reponame=main",
+ "pkg%3Aalpine/nginx%401.10.3-r1%3Farch%3Darmhf%26distroversion%3Dv3.5%26reponame%3Dmain",
+ ),
+ ("pkg:nginx/nginx@0.9.0?os=windows", "pkg%3Anginx/nginx%400.9.0%3Fos%3Dwindows"),
+ (
+ "pkg:deb/ubuntu/nginx@0.6.34-2ubuntu1~intrepid1",
+ "pkg%3Adeb/ubuntu/nginx%400.6.34-2ubuntu1~intrepid1",
+ ),
+ (
+ "pkg:rpm/redhat/openssl@1:1.0.2k-16.el7_6?arch=1",
+ "pkg%3Arpm/redhat/openssl%401%3A1.0.2k-16.el7_6%3Farch%3D1",
+ ),
+ (
+ "pkg:golang/google.golang.org/genproto#googleapis/api/annotations",
+ "pkg%3Agolang/google.golang.org/genproto%23googleapis/api/annotations",
+ ),
+ (
+ "pkg:cocoapods/GoogleUtilities@7.5.2#NSData+zlib",
+ "pkg%3Acocoapods/GoogleUtilities%407.5.2%23NSData%2Bzlib",
+ ),
+ (
+ "pkg:conda/absl-py@0.4.1?build=py36h06a4308_0&channel=main&subdir=linux-64&type=tar.bz2",
+ "pkg%3Aconda/absl-py%400.4.1%3Fbuild%3Dpy36h06a4308_0%26channel%3Dmain%26subdir%3Dlinux-64%26type%3Dtar.bz2",
+ ),
+ ],
+ )
+ def test_url_quote_filter(self, input_value, expected_output):
+ filtered = url_quote_filter(input_value)
+ assert filtered == expected_output
diff --git a/vulnerabilities/views.py b/vulnerabilities/views.py
index 88128b509..394dc1c36 100644
--- a/vulnerabilities/views.py
+++ b/vulnerabilities/views.py
@@ -23,6 +23,8 @@
from django.views import generic
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView
+from univers.version_range import RANGE_CLASS_BY_SCHEMES
+from univers.version_range import AlpineLinuxVersionRange
from vulnerabilities import models
from vulnerabilities.forms import ApiUserCreationForm
@@ -37,6 +39,29 @@
PAGE_SIZE = 20
+def purl_sort_key(purl: models.Package):
+ """
+ Return a sort key for the built-in sorted() function when sorting a list
+ of Package objects. If the Package ``type`` is supported by univers, apply
+ the univers version class to the Package ``version``, and otherwise use the
+ ``version`` attribute as is.
+ """
+ purl_version_class = get_purl_version_class(purl)
+ purl_sort_version = purl.version
+ if purl_version_class:
+ purl_sort_version = purl_version_class(purl.version)
+ return (purl.type, purl.namespace, purl.name, purl_sort_version, purl.qualifiers, purl.subpath)
+
+
+def get_purl_version_class(purl: models.Package):
+ RANGE_CLASS_BY_SCHEMES["alpine"] = AlpineLinuxVersionRange
+ purl_version_class = None
+ check_version_class = RANGE_CLASS_BY_SCHEMES.get(purl.type, None)
+ if check_version_class:
+ purl_version_class = check_version_class.version_class
+ return purl_version_class
+
+
class PackageSearch(ListView):
model = models.Package
template_name = "packages.html"
@@ -159,6 +184,32 @@ def get_context_data(self, **kwargs):
if s.value:
severity_values.add(s.value)
+ sorted_affected_packages = sorted(self.object.affected_packages.all(), key=purl_sort_key)
+ sorted_fixed_by_packages = sorted(self.object.fixed_by_packages.all(), key=purl_sort_key)
+
+ all_affected_fixed_by_matches = []
+ for sorted_affected_package in sorted_affected_packages:
+ affected_fixed_by_matches = {}
+ affected_fixed_by_matches["affected_package"] = sorted_affected_package
+ matched_fixed_by_packages = []
+ for fixed_by_package in sorted_fixed_by_packages:
+ sorted_affected_version_class = get_purl_version_class(sorted_affected_package)
+ fixed_by_version_class = get_purl_version_class(fixed_by_package)
+ if (
+ (fixed_by_package.type == sorted_affected_package.type)
+ and (fixed_by_package.namespace == sorted_affected_package.namespace)
+ and (fixed_by_package.name == sorted_affected_package.name)
+ and (fixed_by_package.qualifiers == sorted_affected_package.qualifiers)
+ and (fixed_by_package.subpath == sorted_affected_package.subpath)
+ and (
+ fixed_by_version_class(fixed_by_package.version)
+ > sorted_affected_version_class(sorted_affected_package.version)
+ )
+ ):
+ matched_fixed_by_packages.append(fixed_by_package.purl)
+ affected_fixed_by_matches["matched_fixed_by_packages"] = matched_fixed_by_packages
+ all_affected_fixed_by_matches.append(affected_fixed_by_matches)
+
context.update(
{
"vulnerability": self.object,
@@ -168,11 +219,12 @@ def get_context_data(self, **kwargs):
"severity_vectors": severity_vectors,
"references": self.object.references.all(),
"aliases": self.object.aliases.all(),
- "affected_packages": self.object.affected_packages.all(),
- "fixed_by_packages": self.object.fixed_by_packages.all(),
+ "affected_packages": sorted_affected_packages,
+ "fixed_by_packages": sorted_fixed_by_packages,
"weaknesses": weaknesses_present_in_db,
"status": status,
"history": self.object.history,
+ "all_affected_fixed_by_matches": all_affected_fixed_by_matches,
}
)
return context
diff --git a/vulnerablecode/static/css/custom.css b/vulnerablecode/static/css/custom.css
index a04427957..6d8918a8f 100644
--- a/vulnerablecode/static/css/custom.css
+++ b/vulnerablecode/static/css/custom.css
@@ -187,12 +187,6 @@ code {
border-color: #dbdbdb;
}
-/* 2023-08-28 Monday 14:55:42. Is this still needed or does wrap-strings take its place? Keep eyes peeled for any odd | displays. */
-/* .table td {
- word-wrap: break-word;
-} */
-
-
.wrap-strings {
word-break: break-word;
}
@@ -356,10 +350,9 @@ a.small_page_button {
}
.details-container {
- border: solid 1px #e8e8e8;
border: 0;
border-radius: 6px;
- box-shadow: 0 0.5em 1em -0.125em rgb(10 10 10 / 10%), 0 0px 0 1px rgb(10 10 10 / 2%);
+ box-shadow: 0 0.5em 1em -0.125em rgba(8, 8, 8, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02);
}
.about-hover-div {
@@ -373,7 +366,7 @@ a.small_page_button {
}
span.tag.custom {
- margin: 0px 0px 6px 10px;
+ margin: 0px 0px 0px 10px;
}
/* CSS for dev fixed by headers */
@@ -428,14 +421,9 @@ span.tag.custom {
border: solid 1px #dbdbdb;
background-color: #ffffff;
}
-/* test bulleted list */
ul.fixed_by_bullet {
list-style-type: disc;
- /*margin-top: 2px;
-margin-bottom: 10px;*/
- /*margin-left: -24px;*/
- /*margin-left: -30px;*/
margin-top: 0.25em;
margin-left: 7px;
margin-bottom: 0.25em;
@@ -444,11 +432,8 @@ margin-bottom: 10px;*/
ul.fixed_by_bullet ul {
list-style-type: disc;
- /*margin-top: 10px;*/
- margin-top: 5px;
margin-top: 0px;
margin-bottom: 0px;
- margin-left: 23px;
margin-left: 18px;
padding: 0;
border: none;
@@ -472,7 +457,6 @@ ul.fixed_by_bullet li:last-child {
font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
font-size: 13px;
font-weight: normal;
- /*margin-bottom: 10px;*/
margin-bottom: 0px;
}
@@ -486,12 +470,11 @@ ul.fixed_by_bullet li li {
color: #000000;
}
-/* 10/10/15 add 3rd-level bullets */
+/* 3rd-level bullets */
ul.fixed_by_bullet ul ul {
list-style-type: disc;
margin-top: 0px;
margin-bottom: 0px;
- margin-left: 50px;
margin-left: 17px;
padding: 0;
border: none;
@@ -569,10 +552,106 @@ ul.fixed_by_bullet li li li {
/* Emphasis for not vulnerable. */
.emphasis-not-vulnerable {
background-color: #e6ffe6;
- /* background-color: #e6ffff; */
+ word-wrap: break-word; word-break: break-all;
+ display: block;
}
/* Emphasis for vulnerable. */
.emphasis-vulnerable {
background-color: #ffe6e6;
}
+
+/* From https://github.com/jgthms/bulma/issues/2040#issuecomment-734507270 (the Bulma GH repo under the author's top-level GH entity). This helps display the responsive navbar dropdown properly < 1024px width. JMH: some added styles to remove box-shadow and make other adjustnments for the collapsed navbar. */
+@media screen and (max-width: 1024px) {
+ .navbar-menu {
+ align-items: stretch;
+ background-color: transparent;
+ font-size: 0.875rem;
+ display: flex;
+ flex-grow: 1;
+ flex-shrink: 0;
+ padding: 0;
+
+ margin-right: 0px !important;
+
+ .navbar-item.is-active .navbar-dropdown,
+ .navbar-item.is-hoverable:focus .navbar-dropdown,
+ .navbar-item.is-hoverable:focus-within .navbar-dropdown,
+ .navbar-item.is-hoverable:hover .navbar-dropdown {
+ display: block;
+ }
+
+ .navbar-end {
+ justify-content: flex-end;
+ margin-left: auto;
+ align-items: stretch;
+ display: flex;
+
+ .navbar-item.has-dropdown {
+ align-items: stretch;
+ }
+
+ .navbar-item,
+ .navbar-link {
+ align-items: center;
+ display: flex;
+ }
+
+ .navbar-dropdown {
+ border-bottom-left-radius: 6px;
+ border-bottom-right-radius: 6px;
+ border-top: 2px solid #dbdbdb;
+ box-shadow: 0 8px 8px rgba(10, 10, 10, 0.1);
+ display: none;
+ font-size: 0.875rem;
+ left: 0;
+ min-width: 100%;
+ position: absolute;
+ top: 100%;
+ z-index: 20;
+ }
+ }
+ }
+
+ /* Make sure the 'About' navbar link hovering div appears left-aligned on narrower screens so it's visible rather than forced beyond the left-hand screen edge. */
+ .dropdown.is-right .dropdown-menu {
+ left: 0;
+ right: auto;
+ }
+
+ /* Remove the collapsed menu's right-hand dark bar, inherited because of how Bulma handles this process. */
+ div.navbar-end.mr-3 {
+ margin-right: 0 !important;
+ }
+
+ .navbar-item,
+ .navbar-item:active,
+ .navbar-item:focus,
+ .navbar-item:visited {
+ color: #ffffff;
+ background-color: transparent;
+ align-items: stretch;
+ display: flex;
+ }
+
+ div.navbar-start {
+ width: 100%;
+ }
+
+ a.navbar-item:focus {
+ background-color: transparent;
+ color: #ffffff;
+ }
+
+ a.navbar-item:hover {
+ color: #ffffff;
+ background-color: #000000;
+ }
+
+}
+
+@media screen and (max-width: 1023px) {
+ .navbar-menu {
+ box-shadow: none;
+ }
+}
|