From 6d544984f2418ea34caab4c433580487b760362a Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Fri, 19 Aug 2011 11:06:55 -0500 Subject: 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 --- lib/libalpm/package.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'lib/libalpm/package.c') diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index d865ac95..3d73a433 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -467,13 +467,32 @@ alpm_pkg_t *_alpm_pkg_new(void) return pkg; } -alpm_pkg_t *_alpm_pkg_dup(alpm_pkg_t *pkg) +/** + * Duplicate a package data struct. + * @param pkg the package to duplicate + * @param new_ptr location to store duplicated package pointer + * @return 0 on success, -1 on fatal error, 1 on non-fatal error + */ +int _alpm_pkg_dup(alpm_pkg_t *pkg, alpm_pkg_t **new_ptr) { alpm_pkg_t *newpkg; alpm_list_t *i; + int ret = 0; + + if(!pkg || !pkg->handle) { + return -1; + } + + if(!new_ptr) { + RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1); + } if(pkg->ops->force_load(pkg)) { - return NULL; + _alpm_log(pkg->handle, ALPM_LOG_WARNING, + _("could not fully load metadata for package %s-%s\n"), + pkg->name, pkg->version); + ret = 1; + pkg->handle->pm_errno = ALPM_ERR_PKG_INVALID; } CALLOC(newpkg, 1, sizeof(alpm_pkg_t), goto cleanup); @@ -540,11 +559,12 @@ alpm_pkg_t *_alpm_pkg_dup(alpm_pkg_t *pkg) newpkg->ops = pkg->ops; newpkg->handle = pkg->handle; - return newpkg; + *new_ptr = newpkg; + return ret; cleanup: _alpm_pkg_free(newpkg); - return NULL; + RET_ERR(pkg->handle, ALPM_ERR_MEMORY, -1); } void _alpm_pkg_free(alpm_pkg_t *pkg) -- cgit v1.2.3-24-g4f1b