[asterisk-commits] twilson: branch twilson/res_config_sqlite3 r334432 - /team/twilson/res_config...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Sep 3 22:44:06 CDT 2011
Author: twilson
Date: Sat Sep 3 22:43:55 2011
New Revision: 334432
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=334432
Log:
Add escaping
Modified:
team/twilson/res_config_sqlite3/res/res_config_sqlite3.c
Modified: team/twilson/res_config_sqlite3/res/res_config_sqlite3.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/res_config_sqlite3/res/res_config_sqlite3.c?view=diff&rev=334432&r1=334431&r2=334432
==============================================================================
--- team/twilson/res_config_sqlite3/res/res_config_sqlite3.c (original)
+++ team/twilson/res_config_sqlite3/res/res_config_sqlite3.c Sat Sep 3 22:43:55 2011
@@ -101,9 +101,69 @@
AST_MUTEX_DEFINE_STATIC(config_lock);
+/* We need a separate buffer for each field we might use concurrently */
+AST_THREADSTORAGE(escape_table_buf);
+AST_THREADSTORAGE(escape_column_buf);
+AST_THREADSTORAGE(escape_value_buf);
+
static int realtime_sqlite3_execute_handle(struct realtime_sqlite3_db *db, const char *sql, int (*callback)(void*, int, char **, char **), void *arg, int sync);
void db_start_batch(struct realtime_sqlite3_db *db);
void db_stop_batch(struct realtime_sqlite3_db *db);
+
+static inline const char *sqlite3_escape_string_helper(struct ast_threadstorage *ts, const char *param)
+{
+ size_t maxlen = strlen(param) * 2 + sizeof("\"\"");
+ /* It doesn't appear that sqlite3_snprintf will do more than double the
+ * length of a string with %q as an option. %Q could double and possibly
+ * add two quotes, and convert NULL pointers to the word "NULL", but we
+ * don't allow those anyway. Just going to use %q for now. */
+ struct ast_str *buf = ast_str_thread_get(ts, maxlen);
+ const char *result;
+ char q = ts == &escape_value_buf ? '\'' : '"';
+
+ ast_str_reset(buf);
+ result = S_OR(sqlite3_snprintf(maxlen, ast_str_buffer(buf), "%c%q%c", q, param, q), "");
+ ast_str_update(buf);
+
+ return result;
+}
+
+static inline const char *sqlite3_escape_table(const char *param)
+{
+ return sqlite3_escape_string_helper(&escape_table_buf, param);
+}
+
+static inline const char *sqlite3_escape_column(const char *param)
+{
+ return sqlite3_escape_string_helper(&escape_column_buf, param);
+}
+
+/* Not inlining this function because it uses strdupa and I don't know if the compiler would be dumb */
+static const char *sqlite3_escape_column_op(const char *param)
+{
+ size_t maxlen = strlen(param) * 2 + sizeof("\"\" =");
+ struct ast_str *buf = ast_str_thread_get(&escape_column_buf, maxlen);
+ char *op, *dup;
+ const char *result;
+
+ dup = ast_strdupa(param);
+
+ if ((op = strchr(dup, ' '))) {
+ *op = '\0';
+ op++;
+ }
+
+ ast_str_reset(buf);
+ result = sqlite3_snprintf(maxlen, ast_str_buffer(buf), "\"%q\" %s", dup, S_OR(op, "="));
+ ast_str_update(buf);
+
+ return result;
+}
+
+static inline const char *sqlite3_escape_value(const char *param)
+{
+ return sqlite3_escape_string_helper(&escape_value_buf, param);
+}
static int db_hash_fn(const void *obj, const int flags)
{
@@ -568,10 +628,12 @@
while ((param = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
if (first) {
- ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s '%s'", table, param, strchr(param, ' ') ? "" : " =", value);
+ ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s %s", sqlite3_escape_table(table),
+ sqlite3_escape_column_op(param), sqlite3_escape_value(value));
first = 0;
} else {
- ast_str_append(&sql, 0, " AND %s%s '%s'", param, strchr(param, ' ') ? "" : " =", value);
+ ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(param),
+ sqlite3_escape_value(value));
}
}
@@ -640,14 +702,15 @@
while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
if (first) {
- ast_str_set(&sql, 0, "UPDATE %s SET `%s` = '%s'", table, key, value);
+ ast_str_set(&sql, 0, "UPDATE %s SET %s = %s",
+ sqlite3_escape_table(table), sqlite3_escape_column(key), sqlite3_escape_value(value));
first = 0;
} else {
- ast_str_append(&sql, 0, ", `%s` = '%s'", key, value);
- }
- }
-
- ast_str_append(&sql, 0, " WHERE %s%s '%s'", keyfield, strchr(keyfield, ' ') ? "" : " =", entity);
+ ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(key), sqlite3_escape_value(value));
+ }
+ }
+
+ ast_str_append(&sql, 0, " WHERE %s %s", sqlite3_escape_column_op(keyfield), sqlite3_escape_value(entity));
res = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
ast_free(sql);
@@ -681,20 +744,20 @@
while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
if (first) {
- ast_str_append(&where_clause, 0, " WHERE %s%s '%s'", key, strchr(key, ' ') ? "" : " =", value);
+ ast_str_set(&where_clause, 0, " WHERE %s %s", sqlite3_escape_column_op(key), sqlite3_escape_value(value));
first = 0;
} else {
- ast_str_append(&where_clause, 0, " AND %s%s '%s'", key, strchr(key, ' ') ? "" : " =", value);
+ ast_str_append(&where_clause, 0, " AND %s %s", sqlite3_escape_column_op(key), sqlite3_escape_value(value));
}
}
first = 1;
while ((key = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
if (first) {
- ast_str_set(&sql, 0, "UPDATE %s SET `%s` = '%s'", table, key, value);
+ ast_str_set(&sql, 0, "UPDATE %s SET %s = %s", sqlite3_escape_table(table), sqlite3_escape_column(key), sqlite3_escape_value(value));
first = 0;
} else {
- ast_str_append(&sql, 0, ", `%s` = '%s'", key, value);
+ ast_str_append(&sql, 0, ", %s = %s", sqlite3_escape_column(key), sqlite3_escape_value(value));
}
}
@@ -733,12 +796,12 @@
while ((column = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
if (first) {
- ast_str_set(&sql, 0, "INSERT INTO %s (`%s`", table, column);
- ast_str_set(&values, 0, ") VALUES ('%s'", value);
+ ast_str_set(&sql, 0, "INSERT INTO %s (%s", sqlite3_escape_table(table), sqlite3_escape_column(column));
+ ast_str_set(&values, 0, ") VALUES (%s", sqlite3_escape_value(value));
first = 0;
} else {
- ast_str_append(&sql, 0, ", `%s`", column);
- ast_str_append(&values, 0, ", '%s'", value);
+ ast_str_append(&sql, 0, ", %s", sqlite3_escape_column(column));
+ ast_str_append(&values, 0, ", %s", sqlite3_escape_value(value));
}
}
@@ -772,10 +835,11 @@
while ((param = va_arg(ap, const char *)) && (value = va_arg(ap, const char *))) {
if (first) {
- ast_str_set(&sql, 0, "DELETE FROM %s WHERE %s%s '%s'", table, param, strchr(param, ' ') ? "" : " =", value);
+ ast_str_set(&sql, 0, "DELETE FROM %s WHERE %s %s", sqlite3_escape_table(table),
+ sqlite3_escape_column_op(param), sqlite3_escape_value(value));
first = 0;
} else {
- ast_str_append(&sql, 0, " AND %s%s '%s'", param, strchr(param, ' ') ? "" : " =", value);
+ ast_str_append(&sql, 0, " AND %s %s", sqlite3_escape_column_op(param), sqlite3_escape_value(value));
}
}
@@ -834,10 +898,11 @@
while ((column = va_arg(ap, typeof(column))) && (type = va_arg(ap, typeof(type))) && (sz = va_arg(ap, typeof(sz)))) {
if (first) {
- ast_str_set(&sql, 0, "CREATE TABLE IF NOT EXISTS %s (%s %s", table, column, get_sqlite_column_type(type));
+ ast_str_set(&sql, 0, "CREATE TABLE IF NOT EXISTS %s (%s %s", sqlite3_escape_table(table),
+ sqlite3_escape_column(column), get_sqlite_column_type(type));
first = 0;
} else {
- ast_str_append(&sql, 0, ", %s %s", column, get_sqlite_column_type(type));
+ ast_str_append(&sql, 0, ", %s %s", sqlite3_escape_column(column), get_sqlite_column_type(type));
}
}
More information about the asterisk-commits
mailing list