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;
}
}
}