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
