AmendHub

Download:

jcs

/

subtext

/

amendments

/

340

folder: Handle malloc/bile failure


jcs made amendment 340 about 1 year ago
--- folder.c Thu Feb 23 21:08:55 2023 +++ folder.c Wed Mar 1 22:29:13 2023 @@ -288,6 +288,7 @@ folder_list_files(struct session *s, struct folder *fo char time[24]; size_t n, off, size; struct folder_file file; + short ret; char *data; session_printf(s, "{{B}}%s: %s (Page %ld of %ld){{/B}}\r\n", @@ -311,10 +312,12 @@ folder_list_files(struct session *s, struct folder *fo size = bile_read_alloc(folder->bile, FOLDER_FILE_RTYPE, file_ids[off + n], &data); - bile_unmarshall_object(folder->bile, folder_file_object_fields, + ret = bile_unmarshall_object(folder->bile, folder_file_object_fields, nfolder_file_object_fields, data, size, &file, sizeof(file), - false, "folder_list_files"); + false); xfree(&data); + if (ret == BILE_ERR_NO_MEMORY) + return; strftime(time, sizeof(time), "%Y-%m-%d", localtime(&file.time)); @@ -366,11 +369,17 @@ folder_upload(struct session *s, struct folder *folder session_flush(s); session_pause_return(s, 0, "when you are ready..."); - upload_path = xmalloc(FILENAME_MAX, "folder_upload path"); + upload_path = xmalloc(FILENAME_MAX); + if (upload_path == NULL) + return 0; snprintf(upload_path, FILENAME_MAX, "%s:upload-%08lx%08lx", folder->path, xorshift32(), xorshift32()); zs = ZCreateReceiver(s, upload_path); + if (zs == NULL) { + xfree(&upload_path); + return 0; + } zs->DoIACEscape = s->is_telnet; ZInit(zs); @@ -448,9 +457,12 @@ folder_upload(struct session *s, struct folder *folder ZDestroy(zs); zs = NULL; + data = xmalloc(1024); + if (data == NULL) + goto file_upload_error; + session_printf(s, "Calculating SHA1 checksum of uploaded file..."); session_flush(s); - data = xmalloc(1024, "folder_upload data"); SHA1Init(&sha1); fp = fopen(upload_path, "rb"); for (n = 1; fp && !feof(fp); n++) { @@ -654,19 +666,22 @@ folder_file_view(struct session *s, struct folder *fol struct session_menu_option *dopts = NULL; FILE *fp; size_t size; - short cc, ret = FILE_VIEW_RETURN_FIND; + short cc, bret, ret = FILE_VIEW_RETURN_FIND; bool done = false, show_help = false; size = bile_read_alloc(folder->bile, FOLDER_FILE_RTYPE, id, &data); if (size == 0) panic("failed fetching message %ld: %d", id, bile_error(folder->bile)); - bile_unmarshall_object(folder->bile, folder_file_object_fields, - nfolder_file_object_fields, data, size, &file, sizeof(file), true, - "folder_file_view"); + bret = bile_unmarshall_object(folder->bile, folder_file_object_fields, + nfolder_file_object_fields, data, size, &file, sizeof(file), true); xfree(&data); - - dopts = xmalloc(sizeof(opts), "folder_file_view opts"); + if (bret == BILE_ERR_NO_MEMORY) + return; + + dopts = xmalloc(sizeof(opts)); + if (dopts == NULL) + return; memcpy(dopts, opts, sizeof(opts)); if (!(s->user && (s->user->is_sysop || s->user->id == file.uploader_user_id))) { @@ -711,7 +726,11 @@ folder_file_view(struct session *s, struct folder *fol switch (c) { case 'd': - path = xmalloc(FILENAME_MAX, "folder_file_view filename"); + path = xmalloc(FILENAME_MAX); + if (path == NULL) { + done = true; + break; + } snprintf(path, FILENAME_MAX, "%s:%s", folder->path, file.filename); fp = fopen(path, "rb"); @@ -721,10 +740,16 @@ folder_file_view(struct session *s, struct folder *fol session_printf(s, "{{B}}Error:{{/B}} Failed opening file\r\n"); xfree(&path); + done = true; break; } zs = ZCreateSender(s, fp, file.filename); + if (zs == NULL) { + xfree(&path); + done = true; + break; + } zs->DoIACEscape = s->is_telnet; ZInit(zs); @@ -831,26 +856,33 @@ folder_find_file_ids(struct folder *folder, size_t *nf char filename[10]; /* only sorted to 10 character places */ } *name_map = NULL, tmp_map; size_t n; - short i, j; + short i, j, ret; char *data; *nfile_ids = bile_count_by_type(folder->bile, FOLDER_FILE_RTYPE); if (*nfile_ids == 0) return 0; - name_map = xcalloc(*nfile_ids, sizeof(struct file_name_map), - "folder_find_file_ids"); - + name_map = xcalloc(*nfile_ids, sizeof(struct file_name_map)); + if (name_map == NULL) + return 0; + for (n = 0; (o = bile_get_nth_of_type(folder->bile, n, FOLDER_FILE_RTYPE)); n++) { if (n >= *nfile_ids) break; - bile_read_alloc(folder->bile, FOLDER_FILE_RTYPE, o->id, &data); - bile_unmarshall_object(folder->bile, folder_file_object_fields, + if (bile_read_alloc(folder->bile, FOLDER_FILE_RTYPE, o->id, + &data) == 0) + break; + ret = bile_unmarshall_object(folder->bile, folder_file_object_fields, nfolder_file_object_fields, data, o->size, &file, sizeof(file), - false, "folder_find_file_ids"); - xfree(&data); + false); xfree(&o); + xfree(&data); + if (ret == 0 && bile_error(folder->bile) == BILE_ERR_NO_MEMORY) { + xfree(&name_map); + return 0; + } name_map[n].id = file.id; strlcpy(name_map[n].filename, file.filename, @@ -869,7 +901,11 @@ folder_find_file_ids(struct folder *folder, size_t *nf } } - *file_ids = xcalloc(sizeof(long), *nfile_ids, "folder_find_file_ids"); + *file_ids = xcalloc(sizeof(long), *nfile_ids); + if (*file_ids == NULL) { + xfree(&name_map); + return 0; + } for (i = 0; i < *nfile_ids; i++) (*file_ids)[i] = name_map[i].id; @@ -883,7 +919,6 @@ bool folder_file_save(struct folder *folder, struct folder_file *file, char *temp_path) { - char note[MALLOC_NOTE_SIZE]; char *new_name = NULL; short ret; char *data; @@ -892,9 +927,8 @@ folder_file_save(struct folder *folder, struct folder_ file->id = bile_next_id(folder->bile, FOLDER_FILE_RTYPE); file->time = Time; - snprintf(note, sizeof(note), "folder_file_save %ld", file->id); ret = bile_marshall_object(folder->bile, folder_file_object_fields, - nfolder_file_object_fields, file, &data, &size, note); + nfolder_file_object_fields, file, &data, &size); if (ret != 0 || size == 0) { warn("failed to marshall new file object"); file->id = 0; @@ -911,7 +945,9 @@ folder_file_save(struct folder *folder, struct folder_ bile_flush(folder->bile, true); - new_name = xmalloc(FILENAME_MAX, "folder_file_save"); + new_name = xmalloc(FILENAME_MAX); + if (new_name == NULL) + return false; snprintf(new_name, FILENAME_MAX, "%s:%s", folder->path, file->filename); CtoPstr(temp_path); @@ -943,7 +979,9 @@ folder_delete_file(struct session *s, struct folder *f BILE_DELETE_FLAG_ZERO | BILE_DELETE_FLAG_PURGE); bile_flush(folder->bile, true); - path = xmalloc(FILENAME_MAX, "folder_delete_file"); + path = xmalloc(FILENAME_MAX); + if (path == NULL) + return; snprintf(path, FILENAME_MAX, "%s:%s", folder->path, file->filename); CtoPstr(path); ret = FSDelete(path, 0); @@ -952,7 +990,7 @@ folder_delete_file(struct session *s, struct folder *f if (ret != 0) session_logf(s, "[%s] Failed deleting %s: %d", folder->name, path, ret); - + xfree(&path); if (file->notes != NULL) xfree(&file->notes); @@ -968,20 +1006,21 @@ folder_file_valid_filename(struct session *session, struct bile_object *o; struct folder_file tfile; size_t len, n; + short ret; char *data; char c; if (file->filename[0] == '\0') { - *error = xstrdup("filename cannot be empty", - "folder_file_valid_filename"); + *error = xstrdup("filename cannot be empty"); return false; } len = strlen(file->filename); if (len > FOLDER_FILE_FILENAME_LENGTH) { - *error = xmalloc(61, "folder_file_valid_filename"); - snprintf(*error, 60, "filename cannot be more than %d characters", - FOLDER_FILE_FILENAME_LENGTH); + *error = xmalloc(61); + if (*error) + snprintf(*error, 60, "filename cannot be more than %d " + "characters", FOLDER_FILE_FILENAME_LENGTH); return false; } @@ -989,23 +1028,22 @@ folder_file_valid_filename(struct session *session, c = file->filename[n]; if (n == 0 && c == '.') { - *error = xstrdup("filename cannot start with a dot", - "folder_file_valid_filename"); + *error = xstrdup("filename cannot start with a dot"); return false; } if (n == len - 1 && c == ' ') { - *error = xstrdup("filename cannot end with a space", - "folder_file_valid_filename"); + *error = xstrdup("filename cannot end with a space"); return false; } if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_' || c == '-' || c == '+' || c == '*' || c == ' ' || c == '.' || c == ',')) { - *error = xmalloc(61, "folder_file_valid_filename"); - snprintf(*error, 60, "filename cannot contain '%c' character", - c); + *error = xmalloc(61); + if (*error) + snprintf(*error, 60, "filename cannot contain '%c' " + "character", c); return false; } } @@ -1017,20 +1055,27 @@ folder_file_valid_filename(struct session *session, continue; } - bile_read_alloc(folder->bile, FOLDER_FILE_RTYPE, o->id, &data); - bile_unmarshall_object(folder->bile, folder_file_object_fields, + ret = bile_read_alloc(folder->bile, FOLDER_FILE_RTYPE, o->id, &data); + if (ret == 0) { + xfree(&o); + return false; + } + ret = bile_unmarshall_object(folder->bile, folder_file_object_fields, nfolder_file_object_fields, data, o->size, &tfile, sizeof(tfile), - false, "folder_file_valid_filename"); + false); xfree(&data); xfree(&o); - + if (ret == BILE_ERR_NO_MEMORY) + return false; + if (strcasecmp(file->filename, tfile.filename) == 0) { - *error = xstrdup("filename is already taken", - "folder_file_valid_filename"); + *error = xstrdup("filename is already taken"); return false; } } - + if (bile_error(folder->bile) == BILE_ERR_NO_MEMORY) + return false; + return true; }