avutil/dict: Improve appending values

When appending two values (due to AV_DICT_APPEND), the earlier code
would first zero-allocate a buffer of the required size and then
copy both parts into it via av_strlcat(). This is problematic,
as it leads to quadratic performance in case of frequent enlargements.
Fix this by using av_realloc() (which is hopefully designed to handle
such cases in a better way than simply throwing the buffer we already
have away) and by copying the string via memcpy() (after all, we already
calculated the strlen of both strings).

Reviewed-by: Paul B Mahol <onemda@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt 2022-09-13 21:07:19 +02:00
parent c15dd31d2a
commit e867a29ec1
1 changed files with 7 additions and 6 deletions

View File

@ -98,16 +98,17 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value,
return 0;
}
if (copy_value && flags & AV_DICT_APPEND) {
size_t len = strlen(tag->value) + strlen(copy_value) + 1;
char *newval = av_mallocz(len);
size_t oldlen = strlen(tag->value);
size_t new_part_len = strlen(copy_value);
size_t len = oldlen + new_part_len + 1;
char *newval = av_realloc(tag->value, len);
if (!newval)
goto err_out;
av_strlcat(newval, tag->value, len);
av_strlcat(newval, copy_value, len);
memcpy(newval + oldlen, copy_value, new_part_len + 1);
av_freep(&copy_value);
copy_value = newval;
}
av_free(tag->value);
} else
av_free(tag->value);
av_free(tag->key);
*tag = m->elems[--m->count];
} else if (copy_value) {