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.

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@176216 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Kevin P. Fleming
2009-02-16 21:10:38 +00:00
parent 22734e39dc
commit 1b5b3efcae

View File

@@ -1256,24 +1256,49 @@ void __ast_string_field_index_build_va(struct ast_string_field_mgr *mgr,
int index, const char *format, va_list ap1, va_list ap2)
{
size_t needed;
size_t available;
char *target;
needed = vsnprintf(mgr->pool->base + mgr->used, mgr->space, format, ap1) + 1;
/* 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;
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;
while (new_size < needed)
new_size *= 2;
if (add_string_pool(mgr, new_size))
return;
target = mgr->pool->base + mgr->used;
}
if (add_string_pool(mgr, new_size))
return;
vsprintf(mgr->pool->base + mgr->used, format, ap2);
vsprintf(target, format, ap2);
}
fields[index] = mgr->pool->base + mgr->used;
fields[index] = target;
mgr->used += needed;
mgr->space -= needed;
}