mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-04 20:04:50 +00:00
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:
45
main/utils.c
45
main/utils.c
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user