summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Schroeder <mls@suse.de>2012-11-27 11:26:32 +0100
committerMichael Schroeder <mls@suse.de>2012-11-27 11:26:32 +0100
commit9eaaeb1ef79617559a51b23acf58f9563478207a (patch)
treeb7bbafe7d15a910a4a6bffff71e31ccd0c6908e3 /src
parentf6d2b5c95e7e49ab9dde3d81d1b4442c82d627ed (diff)
downloadlibsolv-9eaaeb1ef79617559a51b23acf58f9563478207a.tar.gz
libsolv-9eaaeb1ef79617559a51b23acf58f9563478207a.tar.bz2
libsolv-9eaaeb1ef79617559a51b23acf58f9563478207a.zip
make FOR_RULELITERALS safe against whatprovides realloc
Should only make iterating a tiny bit slower, but is more safe and brings the macro in line with the other iterater macros.
Diffstat (limited to 'src')
-rw-r--r--src/problems.c12
-rw-r--r--src/rules.c12
-rw-r--r--src/solver.c67
-rw-r--r--src/solver.h14
4 files changed, 51 insertions, 54 deletions
diff --git a/src/problems.c b/src/problems.c
index afb6639..78911f9 100644
--- a/src/problems.c
+++ b/src/problems.c
@@ -431,12 +431,12 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
if (why >= solv->updaterules && why < solv->updaterules_end)
{
/* update rule, find replacement package */
- Id p, *dp, rp = 0;
+ Id p, pp, rp = 0;
Rule *rr;
/* check if this is a false positive, i.e. the update rule is fulfilled */
rr = solv->rules + why;
- FOR_RULELITERALS(p, dp, rr)
+ FOR_RULELITERALS(p, pp, rr)
if (p > 0 && solv->decisionmap[p] > 0)
return; /* false alarm */
@@ -456,7 +456,7 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
if (rr->w2)
{
int mvrp = 0; /* multi-version replacement */
- FOR_RULELITERALS(rp, dp, rr)
+ FOR_RULELITERALS(rp, pp, rr)
{
if (rp > 0 && solv->decisionmap[rp] > 0 && pool->solvables[rp].repo != solv->installed)
{
@@ -480,11 +480,11 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
if (why >= solv->bestrules && why < solv->bestrules_end)
{
int mvrp;
- Id p, *dp, rp = 0;
+ Id p, pp, rp = 0;
Rule *rr;
/* check false positive */
rr = solv->rules + why;
- FOR_RULELITERALS(p, dp, rr)
+ FOR_RULELITERALS(p, pp, rr)
if (p > 0 && solv->decisionmap[p] > 0)
return; /* false alarm */
/* check update/feature rule */
@@ -507,7 +507,7 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
if (!rr->p)
rr = solv->rules + solv->updaterules + (p - solv->installed->start);
mvrp = 0; /* multi-version replacement */
- FOR_RULELITERALS(rp, dp, rr)
+ FOR_RULELITERALS(rp, pp, rr)
if (rp > 0 && solv->decisionmap[rp] > 0 && pool->solvables[rp].repo != solv->installed)
{
mvrp = rp;
diff --git a/src/rules.c b/src/rules.c
index 12be39b..d16c423 100644
--- a/src/rules.c
+++ b/src/rules.c
@@ -2202,7 +2202,7 @@ void
solver_ruleliterals(Solver *solv, Id rid, Queue *q)
{
Pool *pool = solv->pool;
- Id p, *pp;
+ Id p, pp;
Rule *r;
queue_empty(q);
@@ -2246,7 +2246,7 @@ solver_addchoicerules(Solver *solv)
Rule *r;
Queue q, qi;
int i, j, rid, havechoice;
- Id p, d, *pp;
+ Id p, d, pp;
Id p2, pp2;
Solvable *s, *s2;
Id lastaddedp, lastaddedd;
@@ -2428,7 +2428,7 @@ solver_addchoicerules(Solver *solv)
void
solver_disablechoicerules(Solver *solv, Rule *r)
{
- Id rid, p, *pp;
+ Id rid, p, pp;
Pool *pool = solv->pool;
Map m;
Rule *or;
@@ -2515,7 +2515,7 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs)
if ((solv->job.elements[i] & (SOLVER_JOBMASK | SOLVER_FORCEBEST)) == (SOLVER_INSTALL | SOLVER_FORCEBEST))
{
int j;
- Id p2, *pp2;
+ Id p2, pp2;
for (j = 0; j < solv->ruletojob.count; j++)
if (solv->ruletojob.elements[j] == i)
break;
@@ -2544,7 +2544,7 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs)
{
FOR_REPO_SOLVABLES(installed, p, s)
{
- Id d, p2, *pp2;
+ Id d, p2, pp2;
if (!solv->updatemap_all && (!solv->updatemap.size || !MAPTST(&solv->updatemap, p - installed->start)))
continue;
if (!solv->bestupdatemap_all && (!solv->bestupdatemap.size || !MAPTST(&solv->bestupdatemap, p - installed->start)))
@@ -2694,7 +2694,7 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
Map installedm;
Rule *r;
Id rid, how, what, select;
- Id p, pp, ip, *jp;
+ Id p, pp, ip, jp;
Id req, *reqp, sup, *supp;
Solvable *s;
Queue iq;
diff --git a/src/solver.c b/src/solver.c
index a1dec92..ae0ddcf 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -1544,7 +1544,7 @@ cleandeps_check_mistakes(Solver *solv, int level)
{
Pool *pool = solv->pool;
Rule *r;
- Id p, *dp;
+ Id p, pp;
int i;
int mademistake = 0;
@@ -1557,37 +1557,34 @@ cleandeps_check_mistakes(Solver *solv, int level)
continue;
r = solv->rules + solv->featurerules + (i - solv->installed->start);
/* a mistake is when the featurerule is true but the updaterule is false */
- if (r->p)
- {
- FOR_RULELITERALS(p, dp, r)
- if (p > 0 && solv->decisionmap[p] > 0)
- break;
- if (p)
- {
- r = solv->rules + solv->updaterules + (i - solv->installed->start);
- if (!r->p)
- continue;
- FOR_RULELITERALS(p, dp, r)
- if (p > 0 && solv->decisionmap[p] > 0)
- break;
- if (!p)
- {
- POOL_DEBUG(SOLV_DEBUG_SOLVER, "cleandeps mistake: ");
- solver_printruleclass(solv, SOLV_DEBUG_SOLVER, r);
- POOL_DEBUG(SOLV_DEBUG_SOLVER, "feature rule: ");
- solver_printruleclass(solv, SOLV_DEBUG_SOLVER, solv->rules + solv->featurerules + (i - solv->installed->start));
- if (!solv->cleandeps_mistakes)
- {
- solv->cleandeps_mistakes = solv_calloc(1, sizeof(Queue));
- queue_init(solv->cleandeps_mistakes);
- }
- queue_push(solv->cleandeps_mistakes, i);
- MAPCLR(&solv->cleandepsmap, i - solv->installed->start);
- solver_reenablepolicyrules_cleandeps(solv, i);
- mademistake = 1;
- }
- }
- }
+ if (!r->p)
+ continue;
+ FOR_RULELITERALS(p, pp, r)
+ if (p > 0 && solv->decisionmap[p] > 0)
+ break;
+ if (!p)
+ continue; /* feature rule is not true */
+ r = solv->rules + solv->updaterules + (i - solv->installed->start);
+ if (!r->p)
+ continue;
+ FOR_RULELITERALS(p, pp, r)
+ if (p > 0 && solv->decisionmap[p] > 0)
+ break;
+ if (p)
+ continue; /* update rule is true */
+ POOL_DEBUG(SOLV_DEBUG_SOLVER, "cleandeps mistake: ");
+ solver_printruleclass(solv, SOLV_DEBUG_SOLVER, r);
+ POOL_DEBUG(SOLV_DEBUG_SOLVER, "feature rule: ");
+ solver_printruleclass(solv, SOLV_DEBUG_SOLVER, solv->rules + solv->featurerules + (i - solv->installed->start));
+ if (!solv->cleandeps_mistakes)
+ {
+ solv->cleandeps_mistakes = solv_calloc(1, sizeof(Queue));
+ queue_init(solv->cleandeps_mistakes);
+ }
+ queue_push(solv->cleandeps_mistakes, i);
+ MAPCLR(&solv->cleandepsmap, i - solv->installed->start);
+ solver_reenablepolicyrules_cleandeps(solv, i);
+ mademistake = 1;
}
if (mademistake)
solver_reset(solv);
@@ -1631,7 +1628,7 @@ solver_run_sat(Solver *solv, int disablerules, int doweak)
int i, j, n;
Solvable *s;
Pool *pool = solv->pool;
- Id p, *dp;
+ Id p, pp, *dp;
int minimizationsteps;
int installedpos = solv->installed ? solv->installed->start : 0;
@@ -1694,7 +1691,7 @@ solver_run_sat(Solver *solv, int disablerules, int doweak)
if (r->d < 0) /* ignore disabled rules */
continue;
queue_empty(&dq);
- FOR_RULELITERALS(l, dp, r)
+ FOR_RULELITERALS(l, pp, r)
{
if (l < 0)
{
@@ -1824,7 +1821,7 @@ solver_run_sat(Solver *solv, int disablerules, int doweak)
else
{
/* update to best package */
- FOR_RULELITERALS(p, dp, rr)
+ FOR_RULELITERALS(p, pp, rr)
{
if (solv->decisionmap[p] > 0)
{
diff --git a/src/solver.h b/src/solver.h
index 7ba1f51..5e3a162 100644
--- a/src/solver.h
+++ b/src/solver.h
@@ -266,7 +266,6 @@ typedef struct _Solver Solver;
* you will get problem reported if the best package is
* not installable. This can be used with INSTALL, UPDATE
* and DISTUPGRADE */
-/* Also, it's not implemented yet ;) */
#define SOLVER_FORCEBEST 0x100000
#define SOLVER_SETEV 0x01000000
@@ -340,12 +339,13 @@ void pool_job2solvables(Pool *pool, Queue *pkgs, Id how, Id what);
int pool_isemptyupdatejob(Pool *pool, Id how, Id what);
/* iterate over all literals of a rule */
-/* WARNING: loop body must not relocate whatprovidesdata, e.g. by
- * looking up the providers of a dependency */
-#define FOR_RULELITERALS(l, dp, r) \
- for (l = r->d < 0 ? -r->d - 1 : r->d, \
- dp = !l ? &r->w2 : pool->whatprovidesdata + l, \
- l = r->p; l; l = (dp != &r->w2 + 1 ? *dp++ : 0))
+#define FOR_RULELITERALS(l, pp, r) \
+ for (pp = r->d < 0 ? -r->d - 1 : r->d, \
+ l = r->p; l; l = (pp <= 0 ? (pp-- ? 0 : r->w2) : \
+ pool->whatprovidesdata[pp++]))
+
+
+
/* XXX: this currently doesn't work correctly for SOLVER_SOLVABLE_REPO and
SOLVER_SOLVABLE_ALL */