]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
solver_addbestrules: recalculate pointer to current rule after adding a new rule
authorMichael Schroeder <mls@suse.de>
Fri, 25 Jul 2025 09:08:59 +0000 (11:08 +0200)
committerMichael Schroeder <mls@suse.de>
Fri, 25 Jul 2025 09:10:33 +0000 (11:10 +0200)
The code adds new rules in a FOR_RULELITERALS loop. The iterator needs
to access elements of the rule it iterates over, so if we add a new
rule in the loop body, we have to make sure that the pointer to the
current rule stays valid.

Fixes issue #594

src/rules.c

index 6b1dc037105d4ed4e4313f443d51d79f802d4cee..36960a86e0ce308ce9cb6c055794e31522cadc85 100644 (file)
@@ -3951,12 +3951,17 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs, int haslockjob)
          if (solv->allowuninstall || solv->allowuninstall_all || (solv->allowuninstallmap.size && MAPTST(&solv->allowuninstallmap, p - installed->start)))
            {
              /* package is flagged both for allowuninstall and best, add negative rules */
+             int rid;
              d = q.count == 1 ? q.elements[0] : -pool_queuetowhatprovides(pool, &q);
              for (i = 0; i < q.count; i++)
                MAPSET(&m, q.elements[i]);
-             r = solv->rules + solv->featurerules + (p - installed->start);
+             rid = solv->featurerules + (p - installed->start);
+             r = solv->rules + rid;
              if (!r->p)        /* identical to update rule? */
-               r = solv->rules + solv->updaterules + (p - installed->start);
+               {
+                 rid = solv->updaterules + (p - installed->start);
+                 r = solv->rules + rid;
+               }
              FOR_RULELITERALS(p2, pp2, r)
                {
                  if (MAPTST(&m, p2))
@@ -3966,6 +3971,8 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs, int haslockjob)
                  else
                    solver_addrule(solv, -p2, 0, -d);
                  queue_push(&infoq, p);
+                 /* recalculate r as solver_addrule may have reallocated the rules area */
+                 r = solv->rules + rid;
                }
              for (i = 0; i < q.count; i++)
                MAPCLR(&m, q.elements[i]);