diff options
author | Dan McGee <dan@archlinux.org> | 2011-08-19 18:06:55 +0200 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2011-08-19 18:09:57 +0200 |
commit | 6d544984f2418ea34caab4c433580487b760362a (patch) | |
tree | cf0510b97a6495587c87598a70bf8761189f5c32 /lib/libalpm/remove.c | |
parent | 9934b3bd345011eef6a96249d8d90de594c04cd0 (diff) | |
download | pacman-6d544984f2418ea34caab4c433580487b760362a.tar.gz pacman-6d544984f2418ea34caab4c433580487b760362a.tar.xz |
Be more robust when copying package data
This changes the signature of _alpm_pkg_dup() to return an integer error
code and provide the new package in a passed pointer argument. All
callers are now more robust with checking the return value of this
function to ensure a fatal error did not occur.
We allow load failures to proceed as otherwise we have a chicken and egg
problem- if a 'desc' local database entry is missing, the best way of
restoring said file is `pacman -Sf --dbonly packagename`. This patch
fixes a segfault that was occurring in this case.
Fixes the segfault reported in FS#25667.
Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'lib/libalpm/remove.c')
-rw-r--r-- | lib/libalpm/remove.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index c6886c6f..7903a0f5 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -49,6 +49,7 @@ int SYMEXPORT alpm_remove_pkg(alpm_handle_t *handle, alpm_pkg_t *pkg) { const char *pkgname; alpm_trans_t *trans; + alpm_pkg_t *copy; /* Sanity checks */ CHECK_HANDLE(handle, return -1); @@ -67,11 +68,14 @@ int SYMEXPORT alpm_remove_pkg(alpm_handle_t *handle, alpm_pkg_t *pkg) _alpm_log(handle, ALPM_LOG_DEBUG, "adding package %s to the transaction remove list\n", pkgname); - trans->remove = alpm_list_add(trans->remove, _alpm_pkg_dup(pkg)); + if(_alpm_pkg_dup(pkg, ©) == -1) { + return -1; + } + trans->remove = alpm_list_add(trans->remove, copy); return 0; } -static void remove_prepare_cascade(alpm_handle_t *handle, alpm_list_t *lp) +static int remove_prepare_cascade(alpm_handle_t *handle, alpm_list_t *lp) { alpm_trans_t *trans = handle->trans; @@ -81,14 +85,18 @@ static void remove_prepare_cascade(alpm_handle_t *handle, alpm_list_t *lp) alpm_depmissing_t *miss = i->data; alpm_pkg_t *info = _alpm_db_get_pkgfromcache(handle->db_local, miss->target); if(info) { + alpm_pkg_t *copy; if(!_alpm_pkg_find(trans->remove, info->name)) { _alpm_log(handle, ALPM_LOG_DEBUG, "pulling %s in target list\n", info->name); - trans->remove = alpm_list_add(trans->remove, _alpm_pkg_dup(info)); + if(_alpm_pkg_dup(info, ©) == -1) { + return -1; + } + trans->remove = alpm_list_add(trans->remove, copy); } } else { - _alpm_log(handle, ALPM_LOG_ERROR, _("could not find %s in database -- skipping\n"), - miss->target); + _alpm_log(handle, ALPM_LOG_ERROR, + _("could not find %s in database -- skipping\n"), miss->target); } } alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free); @@ -96,6 +104,7 @@ static void remove_prepare_cascade(alpm_handle_t *handle, alpm_list_t *lp) lp = alpm_checkdeps(handle, _alpm_db_get_pkgcache(handle->db_local), trans->remove, NULL, 1); } + return 0; } static void remove_prepare_keep_needed(alpm_handle_t *handle, alpm_list_t *lp) @@ -134,6 +143,7 @@ static void remove_prepare_keep_needed(alpm_handle_t *handle, alpm_list_t *lp) * the packages blocking the transaction. * @param handle the context handle * @param data a pointer to an alpm_list_t* to fill + * @return 0 on success, -1 on error */ int _alpm_remove_prepare(alpm_handle_t *handle, alpm_list_t **data) { @@ -144,8 +154,10 @@ int _alpm_remove_prepare(alpm_handle_t *handle, alpm_list_t **data) if((trans->flags & ALPM_TRANS_FLAG_RECURSE) && !(trans->flags & ALPM_TRANS_FLAG_CASCADE)) { _alpm_log(handle, ALPM_LOG_DEBUG, "finding removable dependencies\n"); - _alpm_recursedeps(db, trans->remove, - trans->flags & ALPM_TRANS_FLAG_RECURSEALL); + if(_alpm_recursedeps(db, trans->remove, + trans->flags & ALPM_TRANS_FLAG_RECURSEALL)) { + return -1; + } } if(!(trans->flags & ALPM_TRANS_FLAG_NODEPS)) { @@ -156,7 +168,9 @@ int _alpm_remove_prepare(alpm_handle_t *handle, alpm_list_t **data) if(lp != NULL) { if(trans->flags & ALPM_TRANS_FLAG_CASCADE) { - remove_prepare_cascade(handle, lp); + if(remove_prepare_cascade(handle, lp)) { + return -1; + } } else if(trans->flags & ALPM_TRANS_FLAG_UNNEEDED) { /* Remove needed packages (which would break dependencies) * from target list */ @@ -184,7 +198,10 @@ int _alpm_remove_prepare(alpm_handle_t *handle, alpm_list_t **data) if((trans->flags & ALPM_TRANS_FLAG_CASCADE) && (trans->flags & ALPM_TRANS_FLAG_RECURSE)) { _alpm_log(handle, ALPM_LOG_DEBUG, "finding removable dependencies\n"); - _alpm_recursedeps(db, trans->remove, trans->flags & ALPM_TRANS_FLAG_RECURSEALL); + if(_alpm_recursedeps(db, trans->remove, + trans->flags & ALPM_TRANS_FLAG_RECURSEALL)) { + return -1; + } } if(!(trans->flags & ALPM_TRANS_FLAG_NODEPS)) { |