function agent_create creates a copy of the config struct and then calls alloc_string_copy etc to allocate copies of strings.
if any of the allocations fails, it goes to label error and calls agent_destroy.
agent_destroy frees all the allocated strings.
in case that one of the allocations fails, there will be some pointers already allocated with alloc_string_copy, and some pointers unmodified - that is allocated somehow by the caller, which may not be freed in agent_destroy.
function agent_create creates a copy of the config struct and then calls alloc_string_copy etc to allocate copies of strings. if any of the allocations fails, it goes to label error and calls agent_destroy. agent_destroy frees all the allocated strings.
in case that one of the allocations fails, there will be some pointers already allocated with alloc_string_copy, and some pointers unmodified - that is allocated somehow by the caller, which may not be freed in agent_destroy.
the correct approach is to not copy the whole config here: https://github.com/paullouisageneau/libjuice/blob/a2eda1ff9e1726c352e10b060a175d035041ee59/src/agent.c#L74 and instead use alloc_string_copy for individual strings, so that not-yet-copied strings have null values in the agent->config.