Git-Url: 
http://git.frugalware.org/gitweb/gitweb.cgi?p=pacman-g2.git;a=commitdiff;h=25c70049a779ae4936ca98059078c037b93a3873

commit 25c70049a779ae4936ca98059078c037b93a3873
Author: Michel Hermier <[email protected]>
Date:   Wed Sep 3 11:12:35 2014 +0200

libpacman: Make FPtrList swapable, but not copiable (to fix some bugs when 
removing items from lists without a proper copy). Plug a leak 
_pacman_list_remove.

diff --git a/lib/libpacman/conflict.cpp b/lib/libpacman/conflict.cpp
index a0bdc04..ff8cec5 100644
--- a/lib/libpacman/conflict.cpp
+++ b/lib/libpacman/conflict.cpp
@@ -86,7 +86,7 @@ FPtrList *_pacman_checkconflicts(pmtrans_t *trans, FPtrList 
*packages)
}
/* CHECK 1: check targets against database */
_pacman_log(PM_LOG_DEBUG, _("checkconflicts: targ '%s' vs db"), tp->name());
-                       auto cache = _pacman_db_get_pkgcache(db_local);
+                       auto &cache = _pacman_db_get_pkgcache(db_local);
for(auto k = cache.begin(), k_end = cache.end(); k != k_end; k = k->next()) {
Package *dp = (Package *)f_ptrlistitem_data(k);
if(!strcmp(dp->name(), tp->name())) {
@@ -143,7 +143,7 @@ FPtrList *_pacman_checkconflicts(pmtrans_t *trans, FPtrList 
*packages)
}
/* CHECK 3: check database against targets */
_pacman_log(PM_LOG_DEBUG, _("checkconflicts: db vs targ '%s'"), tp->name());
-               auto cache = _pacman_db_get_pkgcache(db_local);
+               auto &cache = _pacman_db_get_pkgcache(db_local);
for(auto k = cache.begin(), k_end = cache.end(); k != k_end; k = k->next()) {
FPtrList *conflicts = NULL;
int usenewconflicts = 0;
diff --git a/lib/libpacman/deps.cpp b/lib/libpacman/deps.cpp
index f69ac1b..c23c67d 100644
--- a/lib/libpacman/deps.cpp
+++ b/lib/libpacman/deps.cpp
@@ -304,7 +304,7 @@ FPtrList *_pacman_checkdeps(pmtrans_t *trans, unsigned char 
op, FPtrList *packag
_pacman_splitdep(depend_name, &depend);
found = 0;
/* check database for literal packages */
-                               auto cache = _pacman_db_get_pkgcache(db_local);
+                               auto &cache = _pacman_db_get_pkgcache(db_local);
for(auto k = cache.begin(), k_end = cache.end(); k != k_end && !found; k = 
k->next()) {
Package *p = (Package *)f_ptrlistitem_data(k);
if(!strcmp(p->name(), depend.name)) {
diff --git a/lib/libpacman/trans.cpp b/lib/libpacman/trans.cpp
index 5c58bc1..9ad6069 100644
--- a/lib/libpacman/trans.cpp
+++ b/lib/libpacman/trans.cpp
@@ -931,7 +931,7 @@ cleanup:
lp = _pacman_sortbydeps(&packages, PM_TRANS_TYPE_ADD);
/* free the old alltargs */
packages.clear();
-               packages = *lp;
+               packages.swap(*lp);
}

if(m_type == PM_TRANS_TYPE_REMOVE && m_type != PM_TRANS_TYPE_UPGRADE) {
@@ -945,7 +945,7 @@ cleanup:
lp = _pacman_sortbydeps(&packages, PM_TRANS_TYPE_REMOVE);
/* free the old alltargs */
packages.clear();
-               packages = *lp;
+               packages.swap(*lp);
}
EVENT(this, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);
}
@@ -1842,7 +1842,7 @@ int __pmtrans_t::commit(FPtrList **data)

/* Update the requiredby field by scanning the whole database
* looking for packages depending on the package to add */
-               auto cache = _pacman_db_get_pkgcache(db_local);
+               auto &cache = _pacman_db_get_pkgcache(db_local);
for(auto lp = cache.begin(), lp_end = cache.end(); lp != lp_end; lp = 
lp->next()) {
Package *tmpp = f_ptrlistitem_data(lp);
if(tmpp == NULL) {
diff --git a/lib/libpacman/util/fptrlist.cpp b/lib/libpacman/util/fptrlist.cpp
index ba90a0f..f086203 100644
--- a/lib/libpacman/util/fptrlist.cpp
+++ b/lib/libpacman/util/fptrlist.cpp
@@ -101,6 +101,7 @@ bool _pacman_list_remove(FPtrList *haystack, void *needle, 
_pacman_fn_cmp fn, vo
if(haystack->m_next) {
haystack->m_next->m_previous = haystack;
}
+                       delete next;
}
return true;
}
@@ -215,16 +216,18 @@ FPtrList *f_ptrlist_add(FPtrList *list, void *data)
list = new FPtrList();
}
#ifndef F_NOCOMPAT
-       FPtrListIterator *lp = f_ptrlist_last(list);
-       if(lp == list && lp->m_data == NULL) {
-               /* nada */
+       if(list->m_data == NULL) {
+               list->m_data = data;
} else {
-               f_ptrlistitem_insert_after(new FCListItem(), lp);
-               lp = lp->m_next;
-       }
-
+#endif
+       FPtrListIterator *lp = f_ptrlist_last(list);
+       f_ptrlistitem_insert_after(new FCListItem(), lp);
+       lp = lp->m_next;
lp->m_data = data;
-#else
+#ifndef F_NOCOMPAT
+       }
+#endif
+#if 0
list->add(data);
#endif

@@ -286,7 +289,7 @@ FPtrListIterator *f_ptrlist_first(FPtrList *self)

const FPtrListIterator *f_ptrlist_first_const(const FPtrList *self)
{
-       return (FPtrListIterator *)self;
+       return (FPtrListIterator *)self->begin();
}

FPtrListIterator *f_ptrlist_last(FPtrList *self)
diff --git a/lib/libpacman/util/fptrlist.h b/lib/libpacman/util/fptrlist.h
index 94479ab..2bd2fc9 100644
--- a/lib/libpacman/util/fptrlist.h
+++ b/lib/libpacman/util/fptrlist.h
@@ -47,6 +47,8 @@ typedef class FCListItem FPtrListIterator;
#endif /* __cplusplus */

#ifdef __cplusplus
+#include <algorithm>
+
extern "C" {
#endif /* __cplusplus */

@@ -334,6 +336,7 @@ public:
friend bool _pacman_list_remove(FPtrList *haystack, void *needle, 
_pacman_fn_cmp fn, void **data);
friend FPtrList *f_ptrlist_add(FPtrList *list, void *data);
friend int f_ptrlistitem_insert_after(FPtrListIterator *self, FPtrListIterator 
*previous);
+       friend class FPtrList;

typedef void *value_type;
typedef value_type *pointer;
@@ -345,7 +348,7 @@ public:
{ }

FCListItem(FCListItem *previous, FCListItem *next)
-               : m_next(next), m_previous(previous)
+               : m_next(next), m_previous(previous), m_data(NULL)
{ }

virtual ~FCListItem()
@@ -356,11 +359,13 @@ public:

FCListItem *next() const
{
+               ASSERT(this != NULL, RET_ERR(PM_ERR_WRONG_ARGS, NULL));
return m_next;
}

FCListItem *previous() const
{
+               ASSERT(this != NULL, RET_ERR(PM_ERR_WRONG_ARGS, NULL));
return m_previous;
}

@@ -406,6 +411,9 @@ public:
typedef FCListItem *iterator;
typedef const iterator const_iterator;

+       FPtrList()
+       { }
+
iterator begin()
{
ASSERT(this != NULL, RET_ERR(PM_ERR_WRONG_ARGS, NULL));
@@ -505,6 +513,27 @@ public:
ASSERT(this != NULL, pm_errno = PM_ERR_WRONG_ARGS; return);
m_next = m_previous = m_data = NULL;
}
+
+       void swap(FPtrList &o) {
+               std::swap(m_data, o.m_data);
+               std::swap(m_next, o.m_next);
+               std::swap(m_previous, o.m_previous);
+               if (m_next != NULL) {
+                       m_next->m_previous = this;
+               }
+               if (m_previous != NULL) {
+                       m_previous->m_next = this;
+               }
+               if (o.m_next != NULL) {
+                       o.m_next->m_previous = &o;
+               }
+               if (o.m_previous != NULL) {
+                       o.m_previous->m_next = &o;
+               }
+       }
+private:
+       FPtrList(const FPtrList &o);
+       FPtrList &operator = (const FPtrList &o);
};
#endif

diff --git a/lib/libpacman/util/fstringlist.cpp 
b/lib/libpacman/util/fstringlist.cpp
index c7da4a1..e2a2384 100644
--- a/lib/libpacman/util/fstringlist.cpp
+++ b/lib/libpacman/util/fstringlist.cpp
@@ -97,7 +97,11 @@ int f_stringlist_delete(FStringList *self)

FStringList *f_stringlist_add(FStringList *list, const char *s)
{
-       return list->add(f_strdup(s));
+       if(list == NULL) {
+               list = new FStringList();
+       }
+       list->add(f_strdup(s));
+       return list;
}

FStringList *f_stringlist_add_stringlist(FStringList *dest, const FStringList 
*src)
_______________________________________________
Frugalware-git mailing list
[email protected]
http://frugalware.org/mailman/listinfo/frugalware-git

Reply via email to