Skip to content

Commit

Permalink
simclist: handle faults during memory allocation
Browse files Browse the repository at this point in the history
fixes several situations that cause segmentation faults
  • Loading branch information
frankmorgner authored and LudovicRousseau committed May 19, 2017
1 parent 8edd183 commit a801c6e
Showing 1 changed file with 81 additions and 30 deletions.
111 changes: 81 additions & 30 deletions src/simclist.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,13 +264,18 @@ static inline long get_random(void) {
int list_init(list_t *restrict l) {
if (l == NULL) return -1;

memset(l, 0, sizeof *l);

seed_random();

l->numels = 0;

/* head/tail sentinels and mid pointer */
l->head_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
l->tail_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
if (NULL == l->tail_sentinel || NULL == l->head_sentinel)
return -1;

l->head_sentinel->next = l->tail_sentinel;
l->tail_sentinel->prev = l->head_sentinel;
l->head_sentinel->prev = l->tail_sentinel->next = l->mid = NULL;
Expand All @@ -284,12 +289,15 @@ int list_init(list_t *restrict l) {
/* free-list attributes */
l->spareels = (struct list_entry_s **)malloc(SIMCLIST_MAX_SPARE_ELEMS * sizeof(struct list_entry_s *));
l->spareelsnum = 0;
if (NULL == l->spareels)
return -1;

#ifdef SIMCLIST_WITH_THREADS
l->threadcount = 0;
#endif

list_attributes_setdefaults(l);
if (list_attributes_setdefaults(l))
return -1;

assert(list_repOk(l));
assert(list_attrOk(l));
Expand Down Expand Up @@ -435,6 +443,9 @@ static inline struct list_entry_s *list_findpos(const list_t *restrict l, int po
float x;
int i;

if (NULL == l->head_sentinel || NULL == l->tail_sentinel)
return NULL;

/* accept 1 slot overflow for fetching head and tail sentinels */
if (posstart < -1 || posstart > (int)l->numels) return NULL;

Expand Down Expand Up @@ -463,6 +474,9 @@ void *list_extract_at(list_t *restrict l, unsigned int pos) {
if (l->iter_active || pos >= l->numels) return NULL;

tmp = list_findpos(l, pos);
if (NULL == tmp)
return NULL;

data = tmp->data;

tmp->data = NULL; /* save data from list_drop_elem() free() */
Expand Down Expand Up @@ -493,13 +507,17 @@ int list_insert_at(list_t *restrict l, const void *data, unsigned int pos) {
/* make room for user' data (has to be copied) */
size_t datalen = l->attrs.meter(data);
lent->data = (struct list_entry_s *)malloc(datalen);
if (NULL == lent->data)
return -1;
memcpy(lent->data, data, datalen);
} else {
lent->data = (void*)data;
}

/* actually append element */
prec = list_findpos(l, pos-1);
if (NULL == prec)
return -1;
succ = prec->next;

prec->next = lent;
Expand Down Expand Up @@ -629,34 +647,36 @@ int list_clear(list_t *restrict l) {

if (l->iter_active) return -1;

if (l->attrs.copy_data) { /* also free user data */
/* spare a loop conditional with two loops: spareing elems and freeing elems */
for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) {
/* move elements as spares as long as there is room */
if (s->data != NULL) free(s->data);
l->spareels[l->spareelsnum++] = s;
}
while (s != l->tail_sentinel) {
/* free the remaining elems */
if (s->data != NULL) free(s->data);
s = s->next;
free(s->prev);
}
l->head_sentinel->next = l->tail_sentinel;
l->tail_sentinel->prev = l->head_sentinel;
} else { /* only free element containers */
/* spare a loop conditional with two loops: spareing elems and freeing elems */
for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) {
/* move elements as spares as long as there is room */
l->spareels[l->spareelsnum++] = s;
}
while (s != l->tail_sentinel) {
/* free the remaining elems */
s = s->next;
free(s->prev);
if (l->head_sentinel && l->tail_sentinel) {
if (l->attrs.copy_data) { /* also free user data */
/* spare a loop conditional with two loops: spareing elems and freeing elems */
for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) {
/* move elements as spares as long as there is room */
if (s->data != NULL) free(s->data);
l->spareels[l->spareelsnum++] = s;
}
while (s != l->tail_sentinel) {
/* free the remaining elems */
if (s->data != NULL) free(s->data);
s = s->next;
free(s->prev);
}
l->head_sentinel->next = l->tail_sentinel;
l->tail_sentinel->prev = l->head_sentinel;
} else { /* only free element containers */
/* spare a loop conditional with two loops: spareing elems and freeing elems */
for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) {
/* move elements as spares as long as there is room */
l->spareels[l->spareelsnum++] = s;
}
while (s != l->tail_sentinel) {
/* free the remaining elems */
s = s->next;
free(s->prev);
}
l->head_sentinel->next = l->tail_sentinel;
l->tail_sentinel->prev = l->head_sentinel;
}
l->head_sentinel->next = l->tail_sentinel;
l->tail_sentinel->prev = l->head_sentinel;
}
l->numels = 0;
l->mid = NULL;
Expand All @@ -678,6 +698,9 @@ int list_locate(const list_t *restrict l, const void *data) {
struct list_entry_s *el;
int pos = 0;

if (NULL == l->head_sentinel || NULL == l->tail_sentinel)
return -1;

if (l->attrs.comparator != NULL) {
/* use comparator */
for (el = l->head_sentinel->next; el != l->tail_sentinel; el = el->next, pos++) {
Expand All @@ -699,6 +722,9 @@ void *list_seek(list_t *restrict l, const void *indicator) {

if (l->attrs.seeker == NULL) return NULL;

if (NULL == l->head_sentinel || NULL == l->tail_sentinel)
return NULL;

for (iter = l->head_sentinel->next; iter != l->tail_sentinel; iter = iter->next) {
if (l->attrs.seeker(iter->data, indicator) != 0) return iter->data;
}
Expand All @@ -719,7 +745,12 @@ int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) {
if (l1 == NULL || l2 == NULL || dest == NULL || l1 == dest || l2 == dest)
return -1;

list_init(dest);
if (NULL == l1->head_sentinel || NULL == l1->tail_sentinel
|| NULL == l2->head_sentinel || NULL == l2->tail_sentinel)
return -1;

if (list_init(dest))
return -1;

dest->numels = l1->numels + l2->numels;
if (dest->numels == 0)
Expand All @@ -730,6 +761,8 @@ int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) {
el = dest->head_sentinel;
while (srcel != l1->tail_sentinel) {
el->next = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
if (NULL == el->next)
return -1;
el->next->prev = el;
el = el->next;
el->data = srcel->data;
Expand All @@ -740,6 +773,8 @@ int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) {
srcel = l2->head_sentinel->next;
while (srcel != l2->tail_sentinel) {
el->next = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
if (NULL == el->next)
return -1;
el->next->prev = el;
el = el->next;
el->data = srcel->data;
Expand Down Expand Up @@ -769,6 +804,10 @@ int list_sort(list_t *restrict l, int versus) {

if (l->numels <= 1)
return 0;

if (NULL == l->head_sentinel || NULL == l->tail_sentinel)
return -1;

list_sort_quicksort(l, versus, 0, l->head_sentinel->next, l->numels-1, l->tail_sentinel->prev);
assert(list_repOk(l));
return 0;
Expand Down Expand Up @@ -907,6 +946,8 @@ static void list_sort_quicksort(list_t *restrict l, int versus,
/* prepare wrapped args, then start thread */
if (l->threadcount < SIMCLIST_MAXTHREADS-1) {
struct list_sort_wrappedparams *wp = (struct list_sort_wrappedparams *)malloc(sizeof(struct list_sort_wrappedparams));
if (NULL == wp)
return -1;
l->threadcount++;
traised = 1;
wp->l = l;
Expand Down Expand Up @@ -937,6 +978,8 @@ static void list_sort_quicksort(list_t *restrict l, int versus,

int list_iterator_start(list_t *restrict l) {
if (l->iter_active) return 0;
if (NULL == l->head_sentinel)
return -1;
l->iter_pos = 0;
l->iter_active = 1;
l->iter_curentry = l->head_sentinel->next;
Expand Down Expand Up @@ -1281,6 +1324,8 @@ int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len
if (l->attrs.unserializer != NULL) {
/* use unserializer */
buf = malloc(header.elemlen);
if (NULL == buf)
return -1;
for (cnt = 0; cnt < header.numels; cnt++) {
READ_ERRCHECK(fd, buf, header.elemlen);
list_append(l, l->attrs.unserializer(buf, & elsize));
Expand All @@ -1290,6 +1335,8 @@ int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len
/* copy verbatim into memory */
for (cnt = 0; cnt < header.numels; cnt++) {
buf = malloc(header.elemlen);
if (NULL == buf)
return -1;
READ_ERRCHECK(fd, buf, header.elemlen);
list_append(l, buf);
}
Expand All @@ -1303,6 +1350,8 @@ int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len
for (cnt = 0; cnt < header.numels; cnt++) {
READ_ERRCHECK(fd, & elsize, sizeof(elsize));
buf = malloc((size_t)elsize);
if (NULL == buf)
return -1;
READ_ERRCHECK(fd, buf, elsize);
totreadlen += elsize;
list_append(l, l->attrs.unserializer(buf, & elsize));
Expand All @@ -1313,6 +1362,8 @@ int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len
for (cnt = 0; cnt < header.numels; cnt++) {
READ_ERRCHECK(fd, & elsize, sizeof(elsize));
buf = malloc(elsize);
if (NULL == buf)
return -1;
READ_ERRCHECK(fd, buf, elsize);
totreadlen += elsize;
list_append(l, buf);
Expand Down Expand Up @@ -1404,7 +1455,7 @@ static int list_drop_elem(list_t *restrict l, struct list_entry_s *tmp, unsigned
if (l->attrs.copy_data && tmp->data != NULL)
free(tmp->data);

if (l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS) {
if (l->spareels != NULL && l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS) {
l->spareels[l->spareelsnum++] = tmp;
} else {
free(tmp);
Expand Down

0 comments on commit a801c6e

Please sign in to comment.