From 17119260034bb09e4984d9fba14edf8f5560399a Mon Sep 17 00:00:00 2001 From: nova Date: Fri, 1 May 2026 22:17:33 +0200 Subject: [PATCH] string escaping --- backend.c | 65 ++++++++++++++++++++++++++++++++++--------------- backend.h | 2 +- file_previews.c | 50 +++++++++++++++++-------------------- file_previews.h | 4 +-- interactions.c | 11 ++++----- threading.c | 14 ++++++----- 6 files changed, 85 insertions(+), 61 deletions(-) diff --git a/backend.c b/backend.c index 846061f..d51f609 100644 --- a/backend.c +++ b/backend.c @@ -80,27 +80,54 @@ char* smartstrcasestr(const char *haystack, const char *needle){ return ret; } -char* parse_cmd_char(const char *cmd, const char *path){ - char *index = strstr(cmd, SETTINGS_COMMAND_REPLACE_STR); - char *out; - if (index) { - out = malloc(strlen(cmd) + 1 + strlen(path) + 1); - char *o = out; - memcpy(out, cmd, index - cmd); - o += index-cmd; - *o = '\"'; - o++; - memcpy(o, path, strlen(path)); - o += strlen(path); - *o = '\"'; - memcpy(o+1, index + 1, strlen(index+1)); - *(o+strlen(index+1)+1) = '\0'; - return out; +char* parse_cmd(const char *cmd, file *f){ + const char *offset = strstr(cmd, SETTINGS_COMMAND_REPLACE_STR); + + int count = 0; + char *out; + char *pos; + unsigned long i = 0; + while(f->file_name[i]) { + if (f->file_name[i] == '\'') { + count++; + } + i++; + } + + out = malloc(strlen(cmd) + 1 + (strlen(f->file_name)+(count*3)) + 1); + + pos = out; + if (offset) { + memcpy(pos, cmd, offset - cmd); + pos += offset - cmd + 1; } else { - concat(out, cmd, " ./\"", 0); - concat(out, out, path, 1); - concat(out, out, "\"", 1); + memcpy(pos, cmd, strlen(cmd)); + pos += strlen(cmd) + 1; + } + pos[-1] = ' '; + pos[0] = '\''; + pos++; + + i = 0; + while(f->file_name[i]) { + if (f->file_name[i] == '\'') { + *pos++ = '\''; + *pos++ = '\\'; + *pos++ = '\''; + } + *pos = f->file_name[i]; + pos++; + i++; + } + *pos = '\''; + + if (offset) { + pos[1]= ' '; + memcpy(pos + 1, offset+1, strlen(offset+1)); + pos[strlen(offset+1)] = '\0'; + } else { + pos[1] = '\0'; } return out; diff --git a/backend.h b/backend.h index eb8d5e9..1fa0ae8 100644 --- a/backend.h +++ b/backend.h @@ -7,5 +7,5 @@ /*char* concat(const char *s1, const char *s2);*/ char* smartstrcasestr(const char *haystack, const char *needle); -char* parse_cmd_char(const char *cmd, const char *path); +char* parse_cmd(const char *cmd, file *f); diff --git a/file_previews.c b/file_previews.c index e0f441e..4f23421 100644 --- a/file_previews.c +++ b/file_previews.c @@ -13,26 +13,19 @@ extern unsigned int terminal_height; extern unsigned int terminal_width; char previewd; -char* text(char *path, unsigned long *file_size); +char* text(file *f); void images_print(char *file_name); void images_clear(); -char* generic(char *path); +char* generic(file *f); -char* get_mimetype(char *path){ - static char *cmd_str = "file --mime-type -b ./\""; - unsigned long cmd_len = strlen(cmd_str); - unsigned int path_len = strlen(path); - - char *cmd = malloc((cmd_len + path_len) + 2); - memset(cmd, ' ', cmd_len + path_len); - memcpy(cmd, cmd_str, cmd_len); - memcpy(cmd + cmd_len, path, path_len); - cmd[cmd_len + path_len] = '\"'; - cmd[cmd_len + path_len + 1] = '\0'; +char* get_mimetype(file *f){ + static const char *cmd_str = "file --mime-type -b"; + char *cmd = parse_cmd(cmd_str, f); FILE *cmd_open = popen(cmd, "r"); char *line = NULL; size_t size = 0; + free(cmd); if (getline(&line, &size, cmd_open) != -1){ pclose(cmd_open); @@ -42,57 +35,60 @@ char* get_mimetype(char *path){ return "unknown"; } } -char* preview_file(char *file_name, unsigned long file_size){ +char* preview_file(file *f){ /* this calls "file" on path */ char *file_buffer; - char *mime = get_mimetype(file_name); + char *mime = get_mimetype(f); #if SETTINGS_UEBERZUG_IMAGE_PREVIEW != 0 images_clear(); #endif if (strstr(mime, "text")) { - file_buffer = text(file_name, &file_size); + file_buffer = text(f); #if SETTINGS_UEBERZUG_IMAGE_PREVIEW != 0 } else if (strstr(mime, "image")) { - file_buffer = generic(file_name); - images_print(file_name); + file_buffer = generic(f); + images_print(f->file_name); previewd = 1; #endif } else { - file_buffer = generic(file_name); + file_buffer = generic(f); } free(mime); return file_buffer; } -char* text(char *path, unsigned long *file_size){ +char* text(file *f){ unsigned long size = (terminal_width/2) * terminal_height; - if (size > *file_size) { - size = *file_size; + if (size > f->file_size) { + size = f->file_size; } char *file_buffer = malloc(size + 1); - FILE *fp = fopen(path, "r"); + FILE *fp = fopen(f->file_name, "r"); if (fread(file_buffer, size, 1, fp) != 0) { + fclose(fp); file_buffer[size] = '\0'; return file_buffer; } else { + fclose(fp); return "failed reading file"; } } -char* generic(char *path){ - char *cmd; - concat(cmd, "file ./\"", path, 0); - concat(cmd, cmd, "\"", 1); +char* generic(file *f){ + static const char *cmd_str = "file "; + char *cmd = parse_cmd(cmd_str, f); FILE *cmd_open = popen(cmd, "r"); char *line = NULL; size_t size = 0; + + free(cmd); if (getline(&line, &size, cmd_open) != -1) { pclose(cmd_open); return line; diff --git a/file_previews.h b/file_previews.h index fbb9cc4..09f91b0 100644 --- a/file_previews.h +++ b/file_previews.h @@ -4,8 +4,8 @@ #include "config.h" #endif -char* preview_file(char *file_name, unsigned long file_size); -char* get_mimetype(char *path); +char* preview_file(file *f); +char* get_mimetype(file *f); void images_clear(); void ueberzug_init(); #if SETTINGS_UEBERZUG_IMAGE_PREVIEW != 0 diff --git a/interactions.c b/interactions.c index 7e4169c..9bcd1f5 100644 --- a/interactions.c +++ b/interactions.c @@ -234,20 +234,19 @@ void move_right(){ } else { unsigned long i = 0; char match = 0; - char *mime = get_mimetype(mid_content[selected_file_current].file_name); + char *mime = get_mimetype(&mid_content[selected_file_current]); char *extension = strrchr(mid_content[selected_file_current].file_name, '.'); if (extension != NULL) { for (i = 0; i < file_extension_default_count; i++) { if (strstr(extension, file_extension_default_cmd[i].file_extension)) { char *cmd; - concat(cmd, file_extension_default_cmd[i].command, " ./\'", 0); - concat(cmd, cmd, mid_content[selected_file_current].file_name, 1); - concat(cmd, cmd, "\'", 1); - + cmd = parse_cmd(file_extension_default_cmd[i].command, &mid_content[selected_file_current]); + printf("\n%s\n",cmd); if (system(cmd) == -1) { /*do nothing*/ } + free(cmd); curs_set(1); /*for some reason, 1 here turns it invisible once again */ match = 1; status |= (STATUS_RUN_BACKEND | STATUS_UPDATE_SCREEN_RELOAD_FULL | STATUS_RELOAD_DIRECTORY); @@ -259,7 +258,7 @@ void move_right(){ for (i = 0; i < mimetype_default_count; i++) { if (strstr(mime, mimetype_default_cmd[i].mimetype)) { - char *cmd = parse_cmd_char(mimetype_default_cmd[i].command, mid_content[selected_file_current].file_name); + char *cmd = parse_cmd(mimetype_default_cmd[i].command, &mid_content[selected_file_current]); if (system(cmd) == -1) { /*do nothing*/ } diff --git a/threading.c b/threading.c index 41ff626..1945b33 100644 --- a/threading.c +++ b/threading.c @@ -87,8 +87,7 @@ void *thread_mid(){ mid_content->file_size = 0; mid_content->permissions = 0; mid_content->color_pair = 0; - mid_content->file_name = malloc(sizeof(char)); - mid_content->file_name[0] = '\0'; + mid_content->file_name = ""; mid_file_count = 0; @@ -149,14 +148,17 @@ void *thread_lft(){ void *thread_rgt(){ file file_current; + file_current.file_name = NULL; while(!(status & STATUS_QUIT_PROGRAM)){ pthread_mutex_lock(&mutex_rgt); pthread_cond_wait(&cond_rgt, &mutex_rgt); pthread_mutex_lock(&mutex_mid); - char *path = mid_content[selected_file_current].file_name; + free(file_current.file_name); memcpy(&file_current, &mid_content[selected_file_current], sizeof(file)); + file_current.file_name = malloc(strlen(mid_content[selected_file_current].file_name)); + memcpy(file_current.file_name, mid_content[selected_file_current].file_name, strlen(mid_content[selected_file_current].file_name)+1); pthread_mutex_unlock(&mutex_mid); if (file_current.permissions & S_IRUSR) { @@ -173,11 +175,11 @@ void *thread_rgt(){ } free(rgt_content); - rgt_file_count = get_dir_size(path); + rgt_file_count = get_dir_size(file_current.file_name); if (rgt_file_count) { /* fails if dir empty */ rgt_content = malloc(rgt_file_count * sizeof(file)); memset(rgt_content, '\0', rgt_file_count * sizeof(file)); - get_dir_content(path, &rgt_file_count, rgt_content); + get_dir_content(file_current.file_name, &rgt_file_count, rgt_content); rgt_content[0].status &= ~FILE_STATUS_FILE_OPEN; free(rgt_buffer); @@ -203,7 +205,7 @@ void *thread_rgt(){ free(rgt_buffer); rgt_content->file_type = FILE_TYPE_OPEN_FILE; rgt_content->status = FILE_STATUS_HOVER; - rgt_buffer = preview_file(path, file_current.file_size); + rgt_buffer = preview_file(&file_current); } } else { unsigned long i = 0;