mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-30 18:40:46 +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)
|
int index, const char *format, va_list ap1, va_list ap2)
|
||||||
{
|
{
|
||||||
size_t needed;
|
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);
|
va_end(ap1);
|
||||||
|
|
||||||
if (needed > mgr->space) {
|
if (needed > available) {
|
||||||
size_t new_size = mgr->size * 2;
|
/* 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)
|
while (new_size < needed)
|
||||||
new_size *= 2;
|
new_size *= 2;
|
||||||
|
|
||||||
|
if (add_string_pool(mgr, new_size))
|
||||||
|
return;
|
||||||
|
|
||||||
|
target = mgr->pool->base + mgr->used;
|
||||||
|
}
|
||||||
|
|
||||||
if (add_string_pool(mgr, new_size))
|
vsprintf(target, format, ap2);
|
||||||
return;
|
|
||||||
|
|
||||||
vsprintf(mgr->pool->base + mgr->used, format, ap2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fields[index] = mgr->pool->base + mgr->used;
|
fields[index] = target;
|
||||||
mgr->used += needed;
|
mgr->used += needed;
|
||||||
mgr->space -= needed;
|
mgr->space -= needed;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user