summaryrefslogtreecommitdiff
path: root/apt-pkg/algorithms.cc
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2025-01-13 20:25:07 +0100
committerJulian Andres Klode <julian.klode@canonical.com>2025-02-14 19:45:12 +0100
commita356af349cc04b649bc4635c26ff81e3d7c7ade5 (patch)
tree371d71e79e668132df511b15063a8cfce2bb7569 /apt-pkg/algorithms.cc
parentbb9b5bbefb0f19a79e006cc5985f3446243ceee1 (diff)
algorithms: Use smart pointer for 2nd PList
This involves the use of goto to fix undefined behavior in the for-loop restart which temporarily generates a K pointing one element ahead of the start of the array (which is undefined).
Diffstat (limited to 'apt-pkg/algorithms.cc')
-rw-r--r--apt-pkg/algorithms.cc21
1 files changed, 8 insertions, 13 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index f90ff0c3c..a08ecd2c6 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -1291,18 +1291,18 @@ bool pkgProblemResolver::ResolveByKeepInternal()
high score packages cause the removal of lower score packages that
would cause the removal of even lower score packages. */
auto Size = Cache.Head().PackageCount;
- pkgCache::Package **PList = new pkgCache::Package *[Size];
- pkgCache::Package **PEnd = PList;
+ std::unique_ptr<pkgCache::Package *[]> PList{new pkgCache::Package *[Size]};
+ pkgCache::Package **PEnd = &PList[0];
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
*PEnd++ = I;
- std::sort(PList,PEnd,[this](Package *a, Package *b) { return ScoreSort(a, b) < 0; });
+ std::sort(&PList[0],PEnd,[this](Package *a, Package *b) { return ScoreSort(a, b) < 0; });
if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
{
clog << "Show Scores" << endl;
- for (pkgCache::Package **K = PList; K != PEnd; K++)
+ for (pkgCache::Package **K = &PList[0]; K != PEnd; K++)
if (Scores[(*K)->ID] != 0)
{
pkgCache::PkgIterator Pkg(Cache,*K);
@@ -1315,7 +1315,8 @@ bool pkgProblemResolver::ResolveByKeepInternal()
// Consider each broken package
pkgCache::Package **LastStop = 0;
- for (pkgCache::Package **K = PList; K != PEnd; K++)
+restart:
+ for (pkgCache::Package **K = &PList[0]; K != PEnd; K++)
{
pkgCache::PkgIterator I(Cache,*K);
@@ -1333,10 +1334,7 @@ bool pkgProblemResolver::ResolveByKeepInternal()
clog << "Keeping package " << I.FullName(false) << endl;
Cache.MarkKeep(I, false, false);
if (InstOrNewPolicyBroken(I) == false)
- {
- K = PList - 1;
- continue;
- }
+ goto restart;
}
// Isolate the problem dependencies
@@ -1405,15 +1403,12 @@ bool pkgProblemResolver::ResolveByKeepInternal()
// I is an iterator based off our temporary package list,
// so copy the name we need before deleting the temporary list
std::string const LoopingPackage = I.FullName(false);
- delete[] PList;
return _error->Error("Internal Error, pkgProblemResolver::ResolveByKeep is looping on package %s.", LoopingPackage.c_str());
}
LastStop = K;
- K = PList - 1;
+ goto restart;
}
- delete[] PList;
-
if (Cache.BrokenCount() != 0)
return _error->Error(_("Unable to correct problems, you have held broken packages."));