Fix alpm_list_copy_data

So I spent a good 4 hours tracking a bug down tonight due to
alpm_list_copy_data not actually doing what I expected to do. We can't find
the size of an object we don't know the type of, so rewrite it so we pass
in the size explicitly. This was making _alpm_pkg_dup fail and causing all
sorts of other issues.

Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Dan McGee 2007-11-14 22:51:16 -06:00
parent c244cfecf6
commit f75ee71762
3 changed files with 12 additions and 8 deletions

View File

@ -399,21 +399,23 @@ alpm_list_t SYMEXPORT *alpm_list_copy(const alpm_list_t *list)
/**
* @brief Copy a list and copy the data.
*
* The data must be constant size!
* Note that the data elements to be copied should not contain pointers
* and should also be of constant size.
*
* @param list the list to copy
* @param size the size of each data element
*
* @return a copy of the original list, data copied as well
*/
alpm_list_t SYMEXPORT *alpm_list_copy_data(const alpm_list_t *list)
alpm_list_t SYMEXPORT *alpm_list_copy_data(const alpm_list_t *list,
size_t size)
{
const alpm_list_t *lp = list;
alpm_list_t *newlist = NULL;
while(lp) {
void *newdata = calloc(1, sizeof(lp->data));
void *newdata = calloc(1, size);
if(newdata) {
memcpy(newdata, lp->data, sizeof(lp->data));
memcpy(newdata, lp->data, size);
newlist = alpm_list_add(newlist, newdata);
lp = lp->next;
}

View File

@ -60,7 +60,7 @@ alpm_list_t *alpm_list_remove(alpm_list_t *haystack, const void *needle, alpm_li
alpm_list_t *alpm_list_remove_dupes(const alpm_list_t *list);
alpm_list_t *alpm_list_strdup(const alpm_list_t *list);
alpm_list_t *alpm_list_copy(const alpm_list_t *list);
alpm_list_t *alpm_list_copy_data(const alpm_list_t *list);
alpm_list_t *alpm_list_copy_data(const alpm_list_t *list, size_t size);
alpm_list_t *alpm_list_reverse(alpm_list_t *list);
/* item accessors */

View File

@ -675,12 +675,14 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg)
newpkg->conflicts = alpm_list_strdup(alpm_pkg_get_conflicts(pkg));
newpkg->files = alpm_list_strdup(alpm_pkg_get_files(pkg));
newpkg->backup = alpm_list_strdup(alpm_pkg_get_backup(pkg));
newpkg->depends = alpm_list_copy_data(alpm_pkg_get_depends(pkg));
newpkg->depends = alpm_list_copy_data(alpm_pkg_get_depends(pkg),
sizeof(pmdepend_t));
newpkg->optdepends = alpm_list_strdup(alpm_pkg_get_optdepends(pkg));
newpkg->groups = alpm_list_strdup(alpm_pkg_get_groups(pkg));
newpkg->provides = alpm_list_strdup(alpm_pkg_get_provides(pkg));
newpkg->replaces = alpm_list_strdup(alpm_pkg_get_replaces(pkg));
newpkg->deltas = alpm_list_copy_data(alpm_pkg_get_deltas(pkg));
newpkg->deltas = alpm_list_copy_data(alpm_pkg_get_deltas(pkg),
sizeof(pmdelta_t));
/* internal */
if(newpkg->origin == PKG_FROM_FILE) {
newpkg->origin_data.file = strdup(pkg->origin_data.file);