[svn-commits] wdoekes: branch 12 r414566 - in /branches/12: ./ res/res_config_odbc.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue May 27 15:02:10 CDT 2014


Author: wdoekes
Date: Tue May 27 15:02:06 2014
New Revision: 414566

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=414566
Log:
res_config_odbc: Fix old and new ast_string_field memory leaks.

The ODBC realtime driver uses ^NN parameter encoding to cope with the
special meaning of the semi-colon. A semi-colon in a field is
interpreted as if the key was supplied twice, something which isn't
otherwise possible with fixed database columns. E.g. allow=alaw;ulaw
is parsed as allow=alaw and allow=ulaw. A literal semi-colon is
rewritten to ^3B when stored in the database.

The module uses a stringfield to efficiently store the encoded
parameters. However, this stringfield wasn't always freed in some
off-nominal cases.

Commit r413241 fixed initialization so the encoding for INSERT and
DELETE queries wouldn't crash. (Only SELECTs and UPDATEs worked
apparently.) But that commit forgot the frees. This change cleans
that up.

Review: https://reviewboard.asterisk.org/r/3555/
........

Merged revisions 414564 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 414565 from http://svn.asterisk.org/svn/asterisk/branches/11

Modified:
    branches/12/   (props changed)
    branches/12/res/res_config_odbc.c

Propchange: branches/12/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.

Modified: branches/12/res/res_config_odbc.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_config_odbc.c?view=diff&rev=414566&r1=414565&r2=414566
==============================================================================
--- branches/12/res/res_config_odbc.c (original)
+++ branches/12/res/res_config_odbc.c Tue May 27 15:02:06 2014
@@ -184,16 +184,7 @@
 	struct custom_prepare_struct cps = { .sql = sql, .fields = fields, };
 	struct ast_flags connected_flag = { RES_ODBC_CONNECTED };
 
-	if (!fields) {
-		return NULL;
-	}
-
-	if (ast_string_field_init(&cps, 256)) {
-		return NULL;
-	}
-
-	if (!table) {
-		ast_string_field_free_memory(&cps);
+	if (!table || !field) {
 		return NULL;
 	}
 
@@ -201,7 +192,6 @@
 
 	if (!obj) {
 		ast_log(LOG_ERROR, "No database handle available with the name of '%s' (check res_odbc.conf)\n", database);
-		ast_string_field_free_memory(&cps);
 		return NULL;
 	}
 
@@ -214,11 +204,15 @@
 			strcasestr(field->name, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\'" : "");
 	}
 
+	if (ast_string_field_init(&cps, 256)) {
+		ast_odbc_release_obj(obj);
+		return NULL;
+	}
 	stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
+	ast_string_field_free_memory(&cps);
 
 	if (!stmt) {
 		ast_odbc_release_obj(obj);
-		ast_string_field_free_memory(&cps);
 		return NULL;
 	}
 
@@ -227,7 +221,6 @@
 		ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);
 		SQLFreeHandle (SQL_HANDLE_STMT, stmt);
 		ast_odbc_release_obj(obj);
-		ast_string_field_free_memory(&cps);
 		return NULL;
 	}
 
@@ -235,14 +228,12 @@
 	if (res == SQL_NO_DATA) {
 		SQLFreeHandle (SQL_HANDLE_STMT, stmt);
 		ast_odbc_release_obj(obj);
-		ast_string_field_free_memory(&cps);
 		return NULL;
 	}
 	if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 		ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
 		SQLFreeHandle (SQL_HANDLE_STMT, stmt);
 		ast_odbc_release_obj(obj);
-		ast_string_field_free_memory(&cps);
 		return NULL;
 	}
 	for (x = 0; x < colcount; x++) {
@@ -256,7 +247,6 @@
 			if (var)
 				ast_variables_destroy(var);
 			ast_odbc_release_obj(obj);
-			ast_string_field_free_memory(&cps);
 			return NULL;
 		}
 
@@ -296,10 +286,8 @@
 		}
 	}
 
-
 	SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 	ast_odbc_release_obj(obj);
-	ast_string_field_free_memory(&cps);
 	return var;
 }
 
@@ -344,13 +332,12 @@
 	SQLLEN indicator;
 	struct custom_prepare_struct cps = { .sql = sql, .fields = fields, };
 
-	if (!table || !field || ast_string_field_init(&cps, 256)) {
+	if (!table || !field) {
 		return NULL;
 	}
 
 	obj = ast_odbc_request_obj2(database, connected_flag);
 	if (!obj) {
-		ast_string_field_free_memory(&cps);
 		return NULL;
 	}
 
@@ -370,11 +357,15 @@
 
 	snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " ORDER BY %s", initfield);
 
+	if (ast_string_field_init(&cps, 256)) {
+		ast_odbc_release_obj(obj);
+		return NULL;
+	}
 	stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
+	ast_string_field_free_memory(&cps);
 
 	if (!stmt) {
 		ast_odbc_release_obj(obj);
-		ast_string_field_free_memory(&cps);
 		return NULL;
 	}
 
@@ -383,7 +374,6 @@
 		ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);
 		SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 		ast_odbc_release_obj(obj);
-		ast_string_field_free_memory(&cps);
 		return NULL;
 	}
 
@@ -392,7 +382,6 @@
 		ast_log(LOG_WARNING, "Out of memory!\n");
 		SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 		ast_odbc_release_obj(obj);
-		ast_string_field_free_memory(&cps);
 		return NULL;
 	}
 
@@ -450,7 +439,6 @@
 
 	SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 	ast_odbc_release_obj(obj);
-	ast_string_field_free_memory(&cps);
 	return cfg;
 }
 
@@ -486,14 +474,9 @@
 		return -1;
 	}
 
-	if (ast_string_field_init(&cps, 256)) {
-		return -1;
-	}
-
 	tableptr = ast_odbc_find_table(database, table);
 	if (!(obj = ast_odbc_request_obj2(database, connected_flag))) {
 		ast_odbc_release_table(tableptr);
-		ast_string_field_free_memory(&cps);
 		return -1;
 	}
 
@@ -525,18 +508,21 @@
 	snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s=?", keyfield);
 	ast_odbc_release_table(tableptr);
 
+	if (ast_string_field_init(&cps, 256)) {
+		ast_odbc_release_obj(obj);
+		return -1;
+	}
 	stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
+	ast_string_field_free_memory(&cps);
 
 	if (!stmt) {
 		ast_odbc_release_obj(obj);
-		ast_string_field_free_memory(&cps);
 		return -1;
 	}
 
 	res = SQLRowCount(stmt, &rowcount);
 	SQLFreeHandle (SQL_HANDLE_STMT, stmt);
 	ast_odbc_release_obj(obj);
-	ast_string_field_free_memory(&cps);
 
 	if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 		ast_log(LOG_WARNING, "SQL Row Count error!\n[%s]\n\n", sql);
@@ -705,10 +691,6 @@
 		return -1;
 	}
 
-	if (ast_string_field_init(&cps, 256)) {
-		return -1;
-	}
-
 	obj = ast_odbc_request_obj2(database, connected_flag);
 	if (!obj) {
 		return -1;
@@ -722,7 +704,12 @@
 	}
 	snprintf(sql, sizeof(sql), "INSERT INTO %s (%s) VALUES (%s)", table, keys, vals);
 
+	if (ast_string_field_init(&cps, 256)) {
+		ast_odbc_release_obj(obj);
+		return -1;
+	}
 	stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
+	ast_string_field_free_memory(&cps);
 
 	if (!stmt) {
 		ast_odbc_release_obj(obj);
@@ -774,10 +761,6 @@
 		return -1;
 	}
 
-	if (ast_string_field_init(&cps, 256)) {
-		return -1;
-	}
-
 	obj = ast_odbc_request_obj2(database, connected_flag);
 	if (!obj) {
 		return -1;
@@ -790,7 +773,12 @@
 	}
 	snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s=?", keyfield);
 
+	if (ast_string_field_init(&cps, 256)) {
+		ast_odbc_release_obj(obj);
+		return -1;
+	}
 	stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
+	ast_string_field_free_memory(&cps);
 
 	if (!stmt) {
 		ast_odbc_release_obj(obj);




More information about the svn-commits mailing list