From b8748f4c00263d29d9d30e47172171850d651743 Mon Sep 17 00:00:00 2001
From: Richard Mudgett <rmudgett@digium.com>
Date: Mon, 22 Aug 2011 17:12:16 +0000
Subject: [PATCH] Merged revisions 332761 via svnmerge from
 https://origsvn.digium.com/svn/asterisk/branches/10

................
  r332761 | rmudgett | 2011-08-22 12:05:35 -0500 (Mon, 22 Aug 2011) | 22 lines

  Merged revisions 332759 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.8

  ........
    r332759 | rmudgett | 2011-08-22 12:00:03 -0500 (Mon, 22 Aug 2011) | 15 lines

    Memory leak reading realtime database variable list.

    Calling ast_load_realtime() can leak the last list node if the read list
    only contains empty variable value items.

    * Fixed list filter loop in ast_load_realtime() to delete the list node
    immediately instead of the next time through the loop.  The next time
    through the loop may not happen if the node to delete is the last in the
    list.

    (issue ASTERISK-18277)
    (issue ASTERISK-18265)
    Patches:
          jira_asterisk_18265_v1.8_config.patch (license #5621) patch uploaded by rmudgett
  ........
................


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@332762 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 main/config.c | 54 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 32 insertions(+), 22 deletions(-)

diff --git a/main/config.c b/main/config.c
index 02b2bf6288..ef1b1c8543 100644
--- a/main/config.c
+++ b/main/config.c
@@ -396,6 +396,14 @@ static void ast_comment_destroy(struct ast_comment **comment)
 	*comment = NULL;
 }
 
+static void ast_variable_destroy(struct ast_variable *doomed)
+{
+	ast_comment_destroy(&doomed->precomments);
+	ast_comment_destroy(&doomed->sameline);
+	ast_comment_destroy(&doomed->trailing);
+	ast_free(doomed);
+}
+
 void ast_variables_destroy(struct ast_variable *v)
 {
 	struct ast_variable *vn;
@@ -403,10 +411,7 @@ void ast_variables_destroy(struct ast_variable *v)
 	while (v) {
 		vn = v;
 		v = v->next;
-		ast_comment_destroy(&vn->precomments);
-		ast_comment_destroy(&vn->sameline);
-		ast_comment_destroy(&vn->trailing);
-		ast_free(vn);
+		ast_variable_destroy(vn);
 	}
 }
 
@@ -2142,32 +2147,37 @@ struct ast_variable *ast_load_realtime_all(const char *family, ...)
 
 struct ast_variable *ast_load_realtime(const char *family, ...)
 {
-	struct ast_variable *res, *cur, *prev = NULL, *freeme = NULL;
+	struct ast_variable *res;
+	struct ast_variable *cur;
+	struct ast_variable **prev;
 	va_list ap;
 
 	va_start(ap, family);
 	res = ast_load_realtime_helper(family, ap);
 	va_end(ap);
 
-	/* Eliminate blank entries */
-	for (cur = res; cur; cur = cur->next) {
-		if (freeme) {
-			ast_free(freeme);
-			freeme = NULL;
-		}
-
+	/* Filter the list. */
+	prev = &res;
+	cur = res;
+	while (cur) {
 		if (ast_strlen_zero(cur->value)) {
-			if (prev)
-				prev->next = cur->next;
-			else
-				res = cur->next;
-			freeme = cur;
-		} else if (cur->value[0] == ' ' && cur->value[1] == '\0') {
-			char *vptr = (char *) cur->value;
-			vptr[0] = '\0';
-			prev = cur;
+			/* Eliminate empty entries */
+			struct ast_variable *next;
+
+			next = cur->next;
+			*prev = next;
+			ast_variable_destroy(cur);
+			cur = next;
 		} else {
-			prev = cur;
+			/* Make blank entries empty and keep them. */
+			if (cur->value[0] == ' ' && cur->value[1] == '\0') {
+				char *vptr = (char *) cur->value;
+
+				vptr[0] = '\0';
+			}
+
+			prev = &cur->next;
+			cur = cur->next;
 		}
 	}
 	return res;
-- 
GitLab