AmendHub

Download:

jcs

/

subtext

/

amendments

/

336

board: Handle malloc/bile failures


jcs made amendment 336 about 1 year ago
--- board.c Wed Mar 1 09:51:32 2023 +++ board.c Wed Mar 1 22:00:33 2023 @@ -310,7 +310,7 @@ board_list_posts(struct session *s, struct board *boar struct board_thread thread = { 0 }; struct board_post post; struct board_fidonet_post fpost; - short indent, j, k; + short indent, j, k, ret; char *data; session_printf(s, "{{B}}%s: %s (Page %ld of %ld){{/B}}\r\n", @@ -329,11 +329,13 @@ board_list_posts(struct session *s, struct board *boar if (board->fidonet_area[0]) { size = bile_read_alloc(board->bile, BOARD_FIDONET_POST_RTYPE, post_ids[n], &data); - bile_unmarshall_object(board->bile, + ret = bile_unmarshall_object(board->bile, board_fidonet_post_object_fields, nboard_fidonet_post_object_fields, data, size, &fpost, - sizeof(fpost), false, "board_list_posts"); + sizeof(fpost), false); xfree(&data); + if (ret == BILE_ERR_NO_MEMORY) + break; strftime(time, sizeof(time), "%b %d", localtime(&fpost.time)); @@ -348,11 +350,13 @@ board_list_posts(struct session *s, struct board *boar } else { size = bile_read_alloc(board->bile, BOARD_POST_RTYPE, post_ids[n], &data); - bile_unmarshall_object(board->bile, board_post_object_fields, - nboard_post_object_fields, data, size, &post, sizeof(post), - false, "board_list_posts"); + ret = bile_unmarshall_object(board->bile, + board_post_object_fields, nboard_post_object_fields, data, + size, &post, sizeof(post), false); xfree(&data); - + if (ret == BILE_ERR_NO_MEMORY) + break; + if (post.thread_id != thread.thread_id) { if (thread.thread_id) { if (thread.subject != NULL) @@ -364,12 +368,13 @@ board_list_posts(struct session *s, struct board *boar } size = bile_read_alloc(board->bile, BOARD_THREAD_RTYPE, post.thread_id, &data); - bile_unmarshall_object(board->bile, + ret = bile_unmarshall_object(board->bile, board_thread_object_fields, nboard_thread_object_fields, - data, size, &thread, sizeof(thread), true, - "board_list_posts"); + data, size, &thread, sizeof(thread), true); xfree(&data); - + if (ret == BILE_ERR_NO_MEMORY) + break; + for (j = 0; j < nitems(indent_parent_ids); j++) indent_parent_ids[j] = 0; } @@ -449,15 +454,20 @@ board_compose(struct session *s, struct board *board, return 0; } - if (initial_body) - post.body = xstrdup(initial_body, "board_compose body"); + if (initial_body) { + post.body = xstrdup(initial_body); + if (post.body == NULL) + return 0; + } + if (thread) { post.thread_id = thread->thread_id; post.parent_post_id = parent_post->id; - } else - thread = xmalloczero(sizeof(struct board_thread), - "board_compose thread"); - + } else { + thread = xmalloczero(sizeof(struct board_thread)); + if (thread == NULL) + return 0; + } post.sender_user_id = s->user->id; strlcpy(post.via, s->via, sizeof(post.via)); @@ -473,9 +483,11 @@ post_compose_start: thread->subject); session_flush(s); } else { - if (initial_subject && !thread->subject) - thread->subject = xstrdup(initial_subject, - "board_compose subject"); + if (initial_subject && !thread->subject) { + thread->subject = xstrdup(initial_subject); + if (thread->subject == NULL) + return 0; + } for (;;) { session_printf(s, "{{B}}Subject:{{/B}} "); @@ -619,7 +631,9 @@ board_post_read(struct session *s, struct board *board short cc; bool done = false, show_help = false; - dopts = xmalloc(sizeof(opts), "board_post_read opts"); + dopts = xmalloc(sizeof(opts)); + if (dopts == NULL) + return 0; memcpy(dopts, opts, sizeof(opts)); if (board->fidonet_area[0]) { @@ -629,16 +643,17 @@ board_post_read(struct session *s, struct board *board panic("failed fetching message %ld: %d", id, bile_error(board->bile)); - bile_unmarshall_object(board->bile, + ret = bile_unmarshall_object(board->bile, board_fidonet_post_object_fields, nboard_fidonet_post_object_fields, data, size, &fpost, - sizeof(fpost), true, "board_post_read post"); + sizeof(fpost), true); xfree(&data); + if (ret == BILE_ERR_NO_MEMORY) + goto done_reading; - if (!(s->user && s->user->is_sysop)) { + if (!(s->user && s->user->is_sysop)) /* disable deleting */ dopts[1].key[0] = '\0'; - } strftime(time, sizeof(time), "%Y-%m-%d %H:%M:%S", localtime(&fpost.time)); @@ -660,26 +675,28 @@ board_post_read(struct session *s, struct board *board if (size == 0) panic("failed fetching message %ld: %d", id, bile_error(board->bile)); - bile_unmarshall_object(board->bile, board_post_object_fields, - nboard_post_object_fields, data, size, &post, sizeof(post), true, - "board_post_read post"); + ret = bile_unmarshall_object(board->bile, board_post_object_fields, + nboard_post_object_fields, data, size, &post, sizeof(post), true); xfree(&data); + if (ret == BILE_ERR_NO_MEMORY) + goto done_reading; size = bile_read_alloc(board->bile, BOARD_THREAD_RTYPE, post.thread_id, &data); if (size == 0) panic("failed fetching thread %ld: %d", post.thread_id, bile_error(board->bile)); - bile_unmarshall_object(board->bile, board_thread_object_fields, + ret = bile_unmarshall_object(board->bile, board_thread_object_fields, nboard_thread_object_fields, data, size, &thread, - sizeof(thread), true, "board_post_read thread"); + sizeof(thread), true); xfree(&data); - + if (ret == BILE_ERR_NO_MEMORY) + goto done_reading; + if (!(s->user && (s->user->is_sysop || - s->user->id == post.sender_user_id))) { + s->user->id == post.sender_user_id))) /* disable deleting */ dopts[1].key[0] = '\0'; - } sender = user_username(post.sender_user_id); @@ -733,7 +750,6 @@ board_post_read(struct session *s, struct board *board post.id); } else { board_delete_post(s, board, &post, &thread); - session_logf(s, "Deleted post %ld (thread %ld)", post.id, thread.thread_id); } @@ -769,7 +785,8 @@ board_post_read(struct session *s, struct board *board break; } } - + +done_reading: xfree(&dopts); if (board->fidonet_area[0]) { @@ -813,9 +830,10 @@ board_find_post_ids(struct session *s, struct board *b } else nall_post_ids = size / sizeof(long); - *post_ids = xcalloc(sizeof(long), MIN(limit, nall_post_ids), - "post_ids"); - + *post_ids = xcalloc(sizeof(long), MIN(limit, nall_post_ids)); + if (*post_ids == NULL) + return 0; + for (n = 0; n < nall_post_ids; n++) { if (n < offset) continue; @@ -839,9 +857,9 @@ board_post_create(struct board *board, struct board_th { short ret; char *data; - size_t size; + size_t size, insert; ssize_t n, j; - size_t insert; + unsigned long *post_ids, *parent_post_ids; if (post->parent_post_id == 0) { thread->thread_id = bile_next_id(board->bile, BOARD_THREAD_RTYPE); @@ -853,8 +871,7 @@ board_post_create(struct board *board, struct board_th post->time = Time; ret = bile_marshall_object(board->bile, board_post_object_fields, - nboard_post_object_fields, post, &data, &size, - "board_post_create post"); + nboard_post_object_fields, post, &data, &size); if (ret != 0 || size == 0) { warn("failed to marshall new post object"); post->id = 0; @@ -872,11 +889,17 @@ board_post_create(struct board *board, struct board_th if (post->time > thread->last_post_at) thread->last_post_at = post->time; thread->nposts++; - thread->post_ids = xreallocarray(thread->post_ids, thread->nposts, + post_ids = xreallocarray(thread->post_ids, thread->nposts, sizeof(long)); - thread->parent_post_ids = xreallocarray(thread->parent_post_ids, + if (post_ids == NULL) + return 0; + thread->post_ids == post_ids; + parent_post_ids = xreallocarray(thread->parent_post_ids, thread->nposts, sizeof(long)); - + if (parent_post_ids == NULL) + return 0; + thread->parent_post_ids = parent_post_ids; + /* * Add new post id to thread post_ids, but put it in the right * place so that reading post_ids will present the tree in order. @@ -901,8 +924,7 @@ board_post_create(struct board *board, struct board_th thread->parent_post_ids[insert] = post->parent_post_id; ret = bile_marshall_object(board->bile, board_thread_object_fields, - nboard_thread_object_fields, thread, &data, &size, - "board_post_create thread"); + nboard_thread_object_fields, thread, &data, &size); if (ret != 0 || size == 0) { warn("failed to marshall thread object"); post->id = 0; @@ -928,7 +950,7 @@ board_delete_post(struct session *s, struct board *boa struct board_post *post, struct board_thread *thread) { size_t size, n, nn; - char *data; + char *data, *body; char del[50]; short ret; bool childs = false; @@ -952,10 +974,13 @@ board_delete_post(struct session *s, struct board *boa if (!childs) { /* just zap this off the end of the tree */ - new_post_ids = xcalloc(thread->nposts - 1, sizeof(unsigned long), - "board_delete_post new_post_ids"); + new_post_ids = xcalloc(thread->nposts - 1, sizeof(unsigned long)); + if (new_post_ids == NULL) + return; new_parent_post_ids = xcalloc(thread->nposts - 1, - sizeof(unsigned long), "board_delete_post new_parent_post_ids"); + sizeof(unsigned long)); + if (new_parent_post_ids == NULL) + return; for (n = 0, nn = 0; n < thread->nposts; n++) { if (thread->post_ids[n] == post->id) @@ -981,8 +1006,7 @@ board_delete_post(struct session *s, struct board *boa thread->parent_post_ids = new_parent_post_ids; ret = bile_marshall_object(board->bile, board_thread_object_fields, - nboard_thread_object_fields, thread, &data, &size, - "board_delete_post"); + nboard_thread_object_fields, thread, &data, &size); if (ret != 0 || size == 0) { warn("failed to marshall thread object during post delete"); return; @@ -1008,11 +1032,14 @@ board_delete_post(struct session *s, struct board *boa xfree(&post->body); snprintf(del, sizeof(del), "[ Post deleted by %s ]", s->user ? s->user->username : "unknown"); - post->body = xstrdup(del, "board_delete_post deleted body"); + body = xstrdup(del); + if (body == NULL) + return; + post->body = body; post->body_size = strlen(post->body) + 1; ret = bile_marshall_object(board->bile, board_post_object_fields, - nboard_post_object_fields, post, &data, &size, "board_delete_post"); + nboard_post_object_fields, post, &data, &size); if (ret != 0 || size == 0) { warn("failed to marshall updated post object"); return; @@ -1069,7 +1096,7 @@ board_index_sorted_post_ids(struct board *board, }; struct board_fidonet_post fpost; struct board_thread thread; - size_t size, i, j, n, npost_ids, nthread_ids; + size_t ret, size, i, j, n, npost_ids, nthread_ids; unsigned long *post_ids, *thread_ids, tmp_id; struct board_id_time_map *id_map, *thread_map, tmp_map; char *data; @@ -1080,16 +1107,19 @@ board_index_sorted_post_ids(struct board *board, if (npost_ids == 0) goto write_out; - id_map = xcalloc(sizeof(struct board_id_time_map), - npost_ids, "board_id_time_map"); - + id_map = xcalloc(sizeof(struct board_id_time_map), npost_ids); + if (id_map == NULL) + goto write_out; + for (n = 0; n < npost_ids; n++) { /* only read as far as the time */ - bile_read(board->bile, BOARD_FIDONET_POST_RTYPE, + ret = bile_read(board->bile, BOARD_FIDONET_POST_RTYPE, post_ids[n], &fpost, offsetof(struct board_fidonet_post, time) + member_size(struct board_fidonet_post, time)); - + if (ret == 0) + goto write_out; + id_map[n].id = fpost.id; id_map[n].time = fpost.time; } @@ -1116,16 +1146,20 @@ board_index_sorted_post_ids(struct board *board, goto write_out; thread_map = xcalloc(sizeof(struct board_id_time_map), - nthread_ids, "board_id_time_map"); + nthread_ids); + if (thread_map == NULL) + goto write_out; npost_ids = 0; for (n = 0; n < nthread_ids; n++) { size = bile_read_alloc(board->bile, BOARD_THREAD_RTYPE, thread_ids[n], &data); - bile_unmarshall_object(board->bile, board_thread_object_fields, - nboard_thread_object_fields, data, size, &thread, - sizeof(thread), false, "board_id_time_map"); + ret = bile_unmarshall_object(board->bile, + board_thread_object_fields, nboard_thread_object_fields, data, + size, &thread, sizeof(thread), false); xfree(&data); + if (ret == BILE_ERR_NO_MEMORY) + goto write_out; thread_map[n].id = thread.thread_id; thread_map[n].time = thread.last_post_at; @@ -1146,16 +1180,22 @@ board_index_sorted_post_ids(struct board *board, } } - post_ids = xcalloc(sizeof(long), npost_ids, "post_ids"); + post_ids = xcalloc(sizeof(long), npost_ids); + if (post_ids == NULL) + goto write_out; npost_ids = 0; for (j = 0; j < nthread_ids; j++) { size = bile_read_alloc(board->bile, BOARD_THREAD_RTYPE, thread_map[j].id, &data); - bile_unmarshall_object(board->bile, board_thread_object_fields, - nboard_thread_object_fields, data, size, &thread, - sizeof(thread), true, "board_index_post_Ids"); + if (data == NULL) + goto write_out; + ret = bile_unmarshall_object(board->bile, + board_thread_object_fields, nboard_thread_object_fields, data, + size, &thread, sizeof(thread), true); xfree(&data); + if (ret == 0) + goto write_out; /* these are already sorted, and we want to keep thread sort */ for (i = 0; i < thread.nposts; i++)