[asterisk-commits] jrose: branch 12 r422984 - /branches/12/main/config.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Sep 12 11:01:48 CDT 2014


Author: jrose
Date: Fri Sep 12 11:01:36 2014
New Revision: 422984

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=422984
Log:
Realtime: Fix a bug that caused realtime destroy command to crash

Also has could affect with anything that goes through ast_destroy_realtime.
If a CLI user used the command 'realtime destroy <family>' with only a single
column/value pair, Asterisk would crash when trying to create a variable list
from a NULL value.

ASTERISK-24231 #close
Reported by: Niklas Larsson
Review: https://reviewboard.asterisk.org/r/3985/


Modified:
    branches/12/main/config.c

Modified: branches/12/main/config.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/main/config.c?view=diff&rev=422984&r1=422983&r2=422984
==============================================================================
--- branches/12/main/config.c (original)
+++ branches/12/main/config.c Fri Sep 12 11:01:36 2014
@@ -2749,9 +2749,22 @@
 	return result;
 }
 
-#define realtime_arguments_to_fields(ap) realtime_arguments_to_fields2(ap, 0)
-
-static struct ast_variable *realtime_arguments_to_fields2(va_list ap, int skip)
+#define realtime_arguments_to_fields(ap, result) realtime_arguments_to_fields2(ap, 0, result)
+
+/*!
+ * \internal
+ * \brief
+ *
+ * \param ap list of variable arguments
+ * \param skip Skip argument pairs for this number of variables
+ * \param result Address of a variables pointer to store the results
+ *               May be NULL if no arguments are parsed
+ *               Will be NULL on failure.
+ *
+ * \retval 0 on success or empty ap list
+ * \retval -1 on failure
+ */
+static int realtime_arguments_to_fields2(va_list ap, int skip, struct ast_variable **result)
 {
 	struct ast_variable *first, *fields = NULL;
 	const char *newparam;
@@ -2778,10 +2791,14 @@
 	 * using the skip parameter:
 	 *
 	 *     va_start(ap, last);
-	 *     x = realtime_arguments_to_fields(ap);
+	 *     if (realtime_arguments_to_fields(ap, &x)) {
+	 *         // FAILURE CONDITIONS
+	 *     }
 	 *     va_end(ap);
 	 *     va_start(ap, last);
-	 *     y = realtime_arguments_to_fields2(ap, 1);
+	 *     if (realtime_arguments_to_fields2(ap, 1, &y)) {
+	 *         // FAILURE CONDITIONS
+	 *     }
 	 *     va_end(ap);
 	 */
 	while (skip--) {
@@ -2795,10 +2812,15 @@
 
 	/* Load up the first vars. */
 	newparam = va_arg(ap, const char *);
+	if (!newparam) {
+		*result = NULL;
+		return 0;
+	}
 	newval = va_arg(ap, const char *);
 
 	if (!(first = ast_variable_new(newparam, newval, ""))) {
-		return NULL;
+		*result = NULL;
+		return -1;
 	}
 
 	while ((newparam = va_arg(ap, const char *))) {
@@ -2808,7 +2830,8 @@
 		if (!(field = ast_variable_new(newparam, newval, ""))) {
 			ast_variables_destroy(fields);
 			ast_variables_destroy(first);
-			return NULL;
+			*result = NULL;
+			return -1;
 		}
 
 		field->next = fields;
@@ -2818,7 +2841,8 @@
 	first->next = fields;
 	fields = first;
 
-	return fields;
+	*result = fields;
+	return 0;
 }
 
 struct ast_variable *ast_load_realtime_all_fields(const char *family, const struct ast_variable *fields)
@@ -2849,7 +2873,7 @@
 	va_list ap;
 
 	va_start(ap, family);
-	fields = realtime_arguments_to_fields(ap);
+	realtime_arguments_to_fields(ap, &fields);
 	va_end(ap);
 
 	if (fields) {
@@ -2897,11 +2921,18 @@
 struct ast_variable *ast_load_realtime(const char *family, ...)
 {
 	RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
+	int field_res = 0;
 	va_list ap;
 
 	va_start(ap, family);
-	fields = realtime_arguments_to_fields(ap);
+	if (realtime_arguments_to_fields(ap, &fields)) {
+		field_res = -1;
+	}
 	va_end(ap);
+
+	if (field_res) {
+		return NULL;
+	}
 
 	if (!fields) {
 		return NULL;
@@ -3006,7 +3037,7 @@
 	va_list ap;
 
 	va_start(ap, family);
-	fields = realtime_arguments_to_fields(ap);
+	realtime_arguments_to_fields(ap, &fields);
 	va_end(ap);
 
 	if (!fields) {
@@ -3043,7 +3074,7 @@
 	va_list ap;
 
 	va_start(ap, lookup);
-	fields = realtime_arguments_to_fields(ap);
+	realtime_arguments_to_fields(ap, &fields);
 	va_end(ap);
 
 	if (!fields) {
@@ -3083,11 +3114,11 @@
 	/* XXX: If we wanted to pass no lookup fields (select all), we'd be
 	 * out of luck. realtime_arguments_to_fields expects at least one key
 	 * value pair. */
-	lookup_fields = realtime_arguments_to_fields(ap);
+	realtime_arguments_to_fields(ap, &lookup_fields);
 	va_end(ap);
 
 	va_start(ap, family);
-	update_fields = realtime_arguments_to_fields2(ap, 1);
+	realtime_arguments_to_fields2(ap, 1, &lookup_fields);
 	va_end(ap);
 
 	if (!lookup_fields || !update_fields) {
@@ -3124,7 +3155,7 @@
 	va_list ap;
 
 	va_start(ap, family);
-	fields = realtime_arguments_to_fields(ap);
+	realtime_arguments_to_fields(ap, &fields);
 	va_end(ap);
 
 	if (!fields) {
@@ -3157,13 +3188,16 @@
 int ast_destroy_realtime(const char *family, const char *keyfield, const char *lookup, ...)
 {
 	RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
+	int res = 0;
 	va_list ap;
 
 	va_start(ap, lookup);
-	fields = realtime_arguments_to_fields(ap);
+	if (realtime_arguments_to_fields(ap, &fields)) {
+		res = -1;
+	}
 	va_end(ap);
 
-	if (!fields) {
+	if (res) {
 		return -1;
 	}
 




More information about the asterisk-commits mailing list