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;
}