[asterisk-commits] kpfleming: branch 1.4 r176216 - /branches/1.4/main/utils.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Feb 16 15:10:39 CST 2009


Author: kpfleming
Date: Mon Feb 16 15:10:38 2009
New Revision: 176216

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=176216
Log:
fix a flaw in the ast_string_field_build() family of API calls; these functions made no attempt to reuse the space already allocated to a field, so every time the field was written it would allocate new space, leading to what appeared to be a memory leak.


Modified:
    branches/1.4/main/utils.c

Modified: branches/1.4/main/utils.c
URL: http://svn.digium.com/svn-view/asterisk/branches/1.4/main/utils.c?view=diff&rev=176216&r1=176215&r2=176216
==============================================================================
--- branches/1.4/main/utils.c (original)
+++ branches/1.4/main/utils.c Mon Feb 16 15:10:38 2009
@@ -1256,24 +1256,49 @@
 				       int index, const char *format, va_list ap1, va_list ap2)
 {
 	size_t needed;
-
-	needed = vsnprintf(mgr->pool->base + mgr->used, mgr->space, format, ap1) + 1;
+	size_t available;
+	char *target;
+
+	/* if the field already has space allocated, try to reuse it;
+	   otherwise, use the empty space at the end of the current
+	   pool
+	*/
+	if (fields[index][0] != '0') {
+		target = (char *) fields[index];
+		available = strlen(fields[index]);
+	} else {
+		target = mgr->pool->base + mgr->used;
+		available = mgr->space;
+	}
+
+	needed = vsnprintf(target, available, format, ap1) + 1;
 
 	va_end(ap1);
 
-	if (needed > mgr->space) {
-		size_t new_size = mgr->size * 2;
-
-		while (new_size < needed)
-			new_size *= 2;
-
-		if (add_string_pool(mgr, new_size))
-			return;
-
-		vsprintf(mgr->pool->base + mgr->used, format, ap2);
-	}
-
-	fields[index] = mgr->pool->base + mgr->used;
+	if (needed > available) {
+		/* if the space needed can be satisfied by using the current
+		   pool (which could only occur if we tried to use the field's
+		   allocated space and failed), then use that space; otherwise
+		   allocate a new pool
+		*/
+		if (needed <= mgr->space) {
+			target = mgr->pool->base + mgr->used;
+		} else {
+			size_t new_size = mgr->size * 2;
+
+			while (new_size < needed)
+				new_size *= 2;
+			
+			if (add_string_pool(mgr, new_size))
+				return;
+			
+			target = mgr->pool->base + mgr->used;
+		}
+
+		vsprintf(target, format, ap2);
+	}
+
+	fields[index] = target;
 	mgr->used += needed;
 	mgr->space -= needed;
 }




More information about the asterisk-commits mailing list