summaryrefslogtreecommitdiffstats
path: root/lib/libalpm/package.c
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2011-08-19 18:06:55 +0200
committerDan McGee <dan@archlinux.org>2011-08-19 18:09:57 +0200
commit6d544984f2418ea34caab4c433580487b760362a (patch)
treecf0510b97a6495587c87598a70bf8761189f5c32 /lib/libalpm/package.c
parent9934b3bd345011eef6a96249d8d90de594c04cd0 (diff)
downloadpacman-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/package.c')
-rw-r--r--lib/libalpm/package.c28
1 files changed, 24 insertions, 4 deletions
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)