diff options
author | Andrew Gregory <andrew.gregory.8@gmail.com> | 2017-05-11 00:54:55 +0200 |
---|---|---|
committer | Allan McRae <allan@archlinux.org> | 2017-07-06 06:48:03 +0200 |
commit | bcc9c417ae989ffda193083807142171c7a0190f (patch) | |
tree | 8850f30c114e01225c5eb03a253a7c92130b90fd | |
parent | c44c649a5280189ea28a54b82e60fc38279fed23 (diff) | |
download | pacman-bcc9c417ae989ffda193083807142171c7a0190f.tar.gz pacman-bcc9c417ae989ffda193083807142171c7a0190f.tar.xz |
alpm_list: abort on memory allocation failure
This makes it possible to detect a failure in several alpm_list
functions. Previously these functions would continue after a failure,
returning partial results and potentially leaking memory.
Unfortunately, NULL is a valid return value for the affected functions
if the input list is empty, so they still do not have a dedicated error
value. Callers can at least detect an error by checking if the input
list was empty.
Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
-rw-r--r-- | lib/libalpm/alpm_list.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/lib/libalpm/alpm_list.c b/lib/libalpm/alpm_list.c index 0f1b819c..334f67ba 100644 --- a/lib/libalpm/alpm_list.c +++ b/lib/libalpm/alpm_list.c @@ -461,7 +461,10 @@ alpm_list_t SYMEXPORT *alpm_list_remove_dupes(const alpm_list_t *list) alpm_list_t *newlist = NULL; while(lp) { if(!alpm_list_find_ptr(newlist, lp->data)) { - newlist = alpm_list_add(newlist, lp->data); + if(alpm_list_append(&newlist, lp->data) == NULL) { + alpm_list_free(newlist); + return NULL; + } } lp = lp->next; } @@ -480,7 +483,10 @@ alpm_list_t SYMEXPORT *alpm_list_strdup(const alpm_list_t *list) const alpm_list_t *lp = list; alpm_list_t *newlist = NULL; while(lp) { - newlist = alpm_list_add(newlist, strdup(lp->data)); + if(alpm_list_append_strdup(&newlist, lp->data) == NULL) { + FREELIST(newlist); + return NULL; + } lp = lp->next; } return newlist; @@ -498,7 +504,10 @@ alpm_list_t SYMEXPORT *alpm_list_copy(const alpm_list_t *list) const alpm_list_t *lp = list; alpm_list_t *newlist = NULL; while(lp) { - newlist = alpm_list_add(newlist, lp->data); + if(alpm_list_append(&newlist, lp->data) == NULL) { + alpm_list_free(newlist); + return NULL; + } lp = lp->next; } return newlist; @@ -523,8 +532,15 @@ alpm_list_t SYMEXPORT *alpm_list_copy_data(const alpm_list_t *list, void *newdata = malloc(size); if(newdata) { memcpy(newdata, lp->data, size); - newlist = alpm_list_add(newlist, newdata); + if(alpm_list_append(&newlist, newdata) == NULL) { + free(newdata); + FREELIST(newlist); + return NULL; + } lp = lp->next; + } else { + FREELIST(newlist); + return NULL; } } return newlist; @@ -552,7 +568,10 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list) list->prev = NULL; while(lp) { - newlist = alpm_list_add(newlist, lp->data); + if(alpm_list_append(&newlist, lp->data) == NULL) { + alpm_list_free(newlist); + return NULL; + } lp = lp->prev; } list->prev = backup; /* restore tail pointer */ |