From 5f5c3d56c4351513c5faa1d7f0a6aa752c25e010 Mon Sep 17 00:00:00 2001 From: Tristan Riehs Date: Sun, 23 Nov 2025 12:16:48 +0100 Subject: Add single quote escaping --- src/main.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 1fdb506..ed09d30 100644 --- a/src/main.c +++ b/src/main.c @@ -71,12 +71,31 @@ static void assert_db_exists(void) exit(EXIT_FAILURE); } -/* Make sure STR contains no single quote, not to break SQL queries. */ -static void assert_no_single_quote(const char *str) +/* Convert heap-allocated *STR to C string to SQL string, essentially by adding + * single quotes to escape single quotes. */ +static void sanitize_sql_str(char **str) { - /* TODO: perform fancy backslash insertion */ - assert(strchr(str, '\'') == NULL); - assert(strchr(str, ';') == NULL); + int nt = 0; /* total number to insert */ + int len = strlen(*str); + char *new_str; + for (int i = 0; i < len; i++) { + if ((*str)[i] == '\'') + nt++; + } + if (nt == 0) + return; + new_str = malloc(len + 1 + nt); + assert(new_str); + int ni = 0; /* number inserted so far */ + for (int i = 0; i < len; i++) { + if ((*str)[i] == '\'') { + new_str[i+ni] = '\''; + ni++; + } + new_str[i+ni] = (*str)[i]; + } + free(*str); + *str = new_str; } static time_t time_from_str(const char *str) @@ -206,7 +225,7 @@ static void ftag_add_one_file(sqlite3 *db, perror("getline"); exit(EXIT_FAILURE); } - assert_no_single_quote(full_name); + sanitize_sql_str(&full_name); full_name[read_len-1] = '\0'; line_len = read_len+1; @@ -226,7 +245,7 @@ static void ftag_add_one_file(sqlite3 *db, canonicalize(canonical_name, full_name); else canonical_name[read_len-1] = '\0'; - assert_no_single_quote(canonical_name); + sanitize_sql_str(&canonical_name); printf("Enter the description.\n"); line_len = 0; @@ -242,7 +261,7 @@ static void ftag_add_one_file(sqlite3 *db, else { description[read_len-1] = '\0'; } - assert_no_single_quote(description); + sanitize_sql_str(&description); line_len = 64; char *date_str = malloc(line_len); @@ -558,9 +577,9 @@ static void ftag_tag_add(int argc, char **argv) "the tag name and its description\n"); exit(EXIT_FAILURE); } - const char *new_tag_name = argv[0]; + char *new_tag_name = argv[0]; assert(strlen(new_tag_name) <= 255); - assert_no_single_quote(new_tag_name); + sanitize_sql_str(&new_tag_name); char sql[1024]; sqlite3 *db = NULL; @@ -576,9 +595,9 @@ static void ftag_tag_add(int argc, char **argv) sqlite3_check(rc, db); int next_id = table_next_id(db, "tags"); - const char *new_tag_desc = argv[1]; + char *new_tag_desc = argv[1]; assert(strlen(new_tag_desc) <= 600); - assert_no_single_quote(new_tag_desc); + sanitize_sql_str(&new_tag_desc); memset(sql, 0, sizeof(sql)); snprintf(sql, sizeof(sql)-1, "INSERT INTO tags VALUES(%d, '%s', '%s');", -- cgit v1.2.3