//-Wall -Wextra -Wpedantic -Wshadow -Wconversion #include #include #include int main() { printf("(0) %%\n"); const char *p_str_1 = "''"; printf("(1) %ld\n", strlen(p_str_1)); const char *p_str_2 = "'%'"; printf("(2) %ld\n", strlen(p_str_2)); const char *p_str_3 = "'%%'"; printf("(3) %ld\n", strlen(p_str_3)); printf("(str2) %s\n", p_str_2); printf("(str3) %s\n", p_str_3); char *p_esc_str = "Pineapple"; // the ';' character at the end is omitted on purpose const char *p_sql_1 = "SELECT * FROM some_table WHERE some_column LIKE '%"; const char *p_sql_2 = "%'"; size_t sql_1_len = strlen(p_sql_1); size_t sql_2_len = strlen(p_sql_2); size_t esc_str_len = strlen(p_esc_str); size_t offset; char *p_sql = malloc( sql_1_len + esc_str_len + sql_2_len + 1 ); if (!p_sql) { printf("Error: cannot allocate memory (1)\n"); return EXIT_FAILURE; } memcpy(p_sql, p_sql_1, sql_1_len); offset = sql_1_len; memcpy(p_sql + offset, p_esc_str, esc_str_len); offset += esc_str_len; memcpy(p_sql + offset, p_sql_2, sql_2_len); offset += sql_2_len; p_sql[offset] = '\0'; printf("attempt 1: %s\n", p_sql); free(p_sql); /**********/ // the ';' character at the end is omitted on purpose const char *p_sql_f = "SELECT * FROM some_table WHERE some_column LIKE '%%'"; printf("Info: p_sql_f len: %ld\n", strlen(p_sql_f)); p_sql = malloc( strlen(p_sql_f) + esc_str_len + 1 ); if (!p_sql) { printf("Error: cannot allocate memory (2)\n"); return EXIT_FAILURE; } // :) size_t to_cp_len = 50; memcpy(p_sql, p_sql_f, to_cp_len); offset = to_cp_len; size_t cp_offset = to_cp_len; memcpy(p_sql + offset, p_esc_str, esc_str_len); offset += esc_str_len; to_cp_len = 2; memcpy(p_sql + offset, p_sql_f + cp_offset, to_cp_len); offset += to_cp_len; p_sql[offset] = '\0'; printf("attempt 2: %s\n", p_sql); free(p_sql); /**********/ size_t buff_size = sql_1_len + esc_str_len + sql_2_len + 1; p_sql = malloc( buff_size ); if (!p_sql) { printf("Error: cannot allocate memory (3)\n"); return EXIT_FAILURE; } int n = snprintf(p_sql, sql_1_len + 1, "%s", p_sql_1); offset = sql_1_len; n += snprintf(p_sql + offset, esc_str_len + 1, "%s", p_esc_str); offset += esc_str_len; n += snprintf(p_sql + offset, sql_2_len + 1, "%s", p_sql_2); printf ("Info: n (1): %d\n", n); printf("with snprintf (1a): %s\n", p_sql); memset(p_sql, 0, buff_size); n = snprintf(p_sql, buff_size, "%s%s%s", p_sql_1, p_esc_str, p_sql_2); printf ("Info: n (2): %d\n", n); printf("with snprintf (1b): %s\n", p_sql); free(p_sql); /**********/ const char *p_sql_template = "SELECT * FROM some_table WHERE some_column LIKE '%%%s%%'"; n = snprintf(NULL, 0, p_sql_template, p_esc_str) + 1; if (n < 0) { printf("Error: snprintf failed (1)\n"); return EXIT_FAILURE; } size_t query_len = (size_t) n; p_sql = malloc( query_len ); if (!p_sql) { printf("Error: cannot allocate memory (4)\n"); return EXIT_FAILURE; } snprintf(p_sql, query_len, p_sql_template, p_esc_str); printf("with snprintf (2): %s\n", p_sql); free(p_sql); return EXIT_SUCCESS; } /* Output: (0) % (1) 2 (2) 3 (3) 4 (str2) '%' (str3) '%%' attempt 1: SELECT * FROM some_table WHERE some_column LIKE '%Pineapple%' Info: p_sql_f len: 52 attempt 2: SELECT * FROM some_table WHERE some_column LIKE '%Pineapple%' Info: n (1): 61 with snprintf (1a): SELECT * FROM some_table WHERE some_column LIKE '%Pineapple%' Info: n (2): 61 with snprintf (1b): SELECT * FROM some_table WHERE some_column LIKE '%Pineapple%' with snprintf (2): SELECT * FROM some_table WHERE some_column LIKE '%Pineapple%' Valgrind: HEAP SUMMARY: in use at exit: 0 bytes in 0 blocks total heap usage: 5 allocs, 5 frees, 1,272 bytes allocated All heap blocks were freed -- no leaks are possible */