[asterisk-commits] twilson: branch twilson/res_config_sqlite3 r334568 - /team/twilson/res_config...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Sep 6 16:35:59 CDT 2011


Author: twilson
Date: Tue Sep  6 16:35:56 2011
New Revision: 334568

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=334568
Log:
Don't crash on NULL field values and handle escaping quotes ourselves.

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=334568&r1=334567&r2=334568
==============================================================================
--- team/twilson/res_config_sqlite3/res/res_config_sqlite3.c (original)
+++ team/twilson/res_config_sqlite3/res/res_config_sqlite3.c Tue Sep  6 16:35:56 2011
@@ -118,14 +118,22 @@
 	 * 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 ? '\'' : '"'; 
+	char *tmp = ast_str_buffer(buf);
+	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), "");
+	*tmp++ = q; /* Initial quote */
+	while ((*tmp++ = *param++)) {
+		/* Did we just copy a quote? Then double it. */
+		if (*(tmp - 1) == q) {
+			*tmp++ = q;
+		}
+	}
+	*tmp = '\0'; /* Terminate past NULL from copy */
+	*(tmp - 1) = q; /* Replace original NULL with the quote */
 	ast_str_update(buf);
 
-	return result;
+	return ast_str_buffer(buf);
 }
 
 static inline const char *sqlite3_escape_table(const char *param)
@@ -143,21 +151,33 @@
 {
 	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++;
-	}
+	char *tmp = ast_str_buffer(buf);
+	int space = 0;
 
 	ast_str_reset(buf);
-	result = sqlite3_snprintf(maxlen, ast_str_buffer(buf), "\"%q\" %s", dup, S_OR(op, "="));
+	*tmp++ = '"';
+	while ((*tmp++ = *param++)) {
+		/* If we have seen a space, don't double quotes. XXX If we ever make the column/op field
+		 * available to users via an API, we will definitely need to avoid allowing special
+		 * characters like ';' in the data past the space as it will be unquoted data */
+		if (space) {
+			continue;
+		}
+		if (*(tmp - 1) == ' ') {
+			*(tmp - 1) = '"';
+			*tmp++ = ' ';
+			space = 1;
+		} else if (*(tmp - 1) == '"') {
+			*tmp++ = '"';
+		}
+	}
+	if (!space) {
+		strcpy(tmp - 1, "\" =");
+	}
+
 	ast_str_update(buf);
 
-	return result;
+	return ast_str_buffer(buf);
 }
 
 static inline const char *sqlite3_escape_value(const char *param)
@@ -430,13 +450,13 @@
 	int i;
 	struct ast_variable *new;
 
-	if (!(new = ast_variable_new(columns[0], values[0], ""))) {
+	if (!(new = ast_variable_new(columns[0], S_OR(values[0], ""), ""))) {
 		return SQLITE_ABORT;
 	}
 	*head = tail = new;
 
 	for (i = 1; i < num_columns; i++) {
-		if (!(new = ast_variable_new(columns[i], values[i], ""))) {
+		if (!(new = ast_variable_new(columns[i], S_OR(values[i], ""), ""))) {
 			ast_variables_destroy(*head);
 			*head = NULL;
 			return SQLITE_ABORT;




More information about the asterisk-commits mailing list