127 lines
5.0 KiB
Diff
127 lines
5.0 KiB
Diff
|
From 594560870c416d0133b08a64e0632a53a6217f71 Mon Sep 17 00:00:00 2001
|
||
|
From: Marek Blaha <mblaha@redhat.com>
|
||
|
Date: Mon, 20 Jan 2020 09:58:03 +0100
|
||
|
Subject: [PATCH] Fix filtering packages by advisory (RhBug:1770125)
|
||
|
|
||
|
Currently the filter does not work well in situation when more versions
|
||
|
and architectures of advisory packages are available.
|
||
|
|
||
|
Let's have package gjs-1.56.2-6.fc30.x86_64
|
||
|
and two advisories related to gjs package:
|
||
|
FEDORA-2019-f4eb34cf4c
|
||
|
gjs-1.56.2-1.fc30.src
|
||
|
gjs-1.56.2-1.fc30.x86_64
|
||
|
FEDORA-2019-57b5902ed1
|
||
|
gjs-1.56.2-6.fc30.src
|
||
|
gjs-1.56.2-6.fc30.x86_64
|
||
|
|
||
|
In this case the FEDORA-2019-57b5902ed1 advisory is not matched for
|
||
|
gjs-1.56.2-6.fc30.x86_64 package (considering >= operator as in 'dnf
|
||
|
update --bugfix') because only the package of `src` architecture as been
|
||
|
checked. The checking of other versions/architectures was missing.
|
||
|
|
||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1770125
|
||
|
---
|
||
|
libdnf/sack/query.cpp | 63 +++++++++++++++----------------------------
|
||
|
1 file changed, 22 insertions(+), 41 deletions(-)
|
||
|
|
||
|
diff --git a/libdnf/sack/query.cpp b/libdnf/sack/query.cpp
|
||
|
index 6e9e4715f..122a50df6 100644
|
||
|
--- a/libdnf/sack/query.cpp
|
||
|
+++ b/libdnf/sack/query.cpp
|
||
|
@@ -518,9 +518,9 @@ advisoryPkgCompareSolvable(const AdvisoryPkg &first, const Solvable &s)
|
||
|
{
|
||
|
if (first.getName() != s.name)
|
||
|
return first.getName() < s.name;
|
||
|
- if (first.getEVR() != s.evr)
|
||
|
- return first.getEVR() < s.evr;
|
||
|
- return first.getArch() < s.arch;
|
||
|
+ if (first.getArch() != s.arch)
|
||
|
+ return first.getArch() < s.arch;
|
||
|
+ return first.getEVR() < s.evr;
|
||
|
}
|
||
|
|
||
|
static bool
|
||
|
@@ -1607,13 +1607,12 @@ Query::Impl::filterLocation(const Filter & f, Map *m)
|
||
|
|
||
|
/**
|
||
|
* @brief Reduce query to security filters. It reflect following compare types: HY_EQ, HY_GT, HY_LT.
|
||
|
-* In case HY_GT or HY_LT, it first find all advisory packages that EQ to packages in result.
|
||
|
-* Then it adds packages from Result to Map *m if Name and Arch is EQ, and EVR comparison is
|
||
|
-* according to one of selected compare type (HY_EQ, HY_GT, HY_LT).
|
||
|
*
|
||
|
-* @param f p_f:...
|
||
|
-* @param m p_m:...
|
||
|
-* @param keyname p_keyname:...
|
||
|
+* @param f: Filter that should be applied on advisories
|
||
|
+* @param m: Map of query results complying the filter
|
||
|
+* @param keyname: how are the advisories matched. HY_PKG_ADVISORY, HY_PKG_ADVISORY_BUG,
|
||
|
+* HY_PKG_ADVISORY_CVE, HY_PKG_ADVISORY_TYPE and HY_PKG_ADVISORY_SEVERITY
|
||
|
+* are supported
|
||
|
*/
|
||
|
void
|
||
|
Query::Impl::filterAdvisory(const Filter & f, Map *m, int keyname)
|
||
|
@@ -1668,7 +1667,6 @@ Query::Impl::filterAdvisory(const Filter & f, Map *m, int keyname)
|
||
|
// convert nevras (from DnfAdvisoryPkg) to pool ids
|
||
|
Id id = -1;
|
||
|
int cmp_type = f.getCmpType();
|
||
|
- bool cmpTypeGreaterOrLower = cmp_type & HY_GT || cmp_type & HY_LT;
|
||
|
while (true) {
|
||
|
if (pkgs.size() == 0)
|
||
|
break;
|
||
|
@@ -1676,40 +1674,23 @@ Query::Impl::filterAdvisory(const Filter & f, Map *m, int keyname)
|
||
|
if (id == -1)
|
||
|
break;
|
||
|
Solvable* s = pool_id2solvable(pool, id);
|
||
|
- auto low = std::lower_bound(pkgs.begin(), pkgs.end(), *s, advisoryPkgCompareSolvable);
|
||
|
- if (low != pkgs.end() && low->nevraEQ(s)) {
|
||
|
- if (cmpTypeGreaterOrLower) {
|
||
|
- pkgsSecondRun.push_back(*low);
|
||
|
- } else {
|
||
|
+ if (cmp_type == HY_EQ) {
|
||
|
+ auto low = std::lower_bound(pkgs.begin(), pkgs.end(), *s, advisoryPkgCompareSolvable);
|
||
|
+ if (low != pkgs.end() && low->nevraEQ(s)) {
|
||
|
MAPSET(m, id);
|
||
|
}
|
||
|
- }
|
||
|
- }
|
||
|
- if (!cmpTypeGreaterOrLower) {
|
||
|
- return;
|
||
|
- }
|
||
|
- std::sort(pkgsSecondRun.begin(), pkgsSecondRun.end(), advisoryPkgSort);
|
||
|
- id = -1;
|
||
|
- while (true) {
|
||
|
- if (pkgsSecondRun.size() == 0)
|
||
|
- break;
|
||
|
- id = resultPset->next(id);
|
||
|
- if (id == -1)
|
||
|
- break;
|
||
|
- Solvable* s = pool_id2solvable(pool, id);
|
||
|
- auto low = std::lower_bound(pkgsSecondRun.begin(), pkgsSecondRun.end(), *s,
|
||
|
- advisoryPkgCompareSolvableNameArch);
|
||
|
- while (low != pkgsSecondRun.end() && low->getName() == s->name &&
|
||
|
- low->getArch() == s->arch) {
|
||
|
-
|
||
|
- int cmp = pool_evrcmp(pool, s->evr, low->getEVR(), EVRCMP_COMPARE);
|
||
|
- if ((cmp > 0 && cmp_type & HY_GT) ||
|
||
|
- (cmp < 0 && cmp_type & HY_LT) ||
|
||
|
- (cmp == 0 && cmp_type & HY_EQ)) {
|
||
|
- MAPSET(m, id);
|
||
|
- break;
|
||
|
+ } else {
|
||
|
+ auto low = std::lower_bound(pkgs.begin(), pkgs.end(), *s, advisoryPkgCompareSolvableNameArch);
|
||
|
+ while (low != pkgs.end() && low->getName() == s->name && low->getArch() == s->arch) {
|
||
|
+ int cmp = pool_evrcmp(pool, s->evr, low->getEVR(), EVRCMP_COMPARE);
|
||
|
+ if ((cmp > 0 && cmp_type & HY_GT) ||
|
||
|
+ (cmp < 0 && cmp_type & HY_LT) ||
|
||
|
+ (cmp == 0 && cmp_type & HY_EQ)) {
|
||
|
+ MAPSET(m, id);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ ++low;
|
||
|
}
|
||
|
- ++low;
|
||
|
}
|
||
|
}
|
||
|
}
|