You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-commits@axis.apache.org by ro...@apache.org on 2026/01/29 14:26:58 UTC
(axis-axis2-c-core) 04/04: Fix memory leaks in property and session map cleanup
This is an automated email from the ASF dual-hosted git repository.
robertlazarski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/axis-axis2-c-core.git
commit 0410a89ba4eb818acdbbf8418d965c93e86e8853
Author: Robert Lazarski <ro...@gmail.com>
AuthorDate: Thu Jan 29 04:25:49 2026 -1000
Fix memory leaks in property and session map cleanup
Two related memory management fixes:
1. util/src/property.c: Remove erroneous AXIS2_SCOPE_APPLICATION check
in axutil_property_free() and axutil_property_set_value(). The scope
should control property lifetime within a context (whether it persists
across requests), not whether the value should be freed when the
property itself is being destroyed. This check caused memory leaks
when conf_ctx was freed with application-scoped properties like the
cookie session map.
2. http_transport_utils.c: Fix double-free in session_map_free_void_arg().
Don't manually free hash keys since axutil_hash_free() already frees
them when key_is_copy is true (AXIS2C-1632 fix). Only free the values
(cookie strings) which the hash doesn't manage.
These fixes eliminate memory leaks detected by AddressSanitizer in the
cookie persistence test (test_axis2c_1566).
Co-Authored-By: Claude Opus 4.5 <no...@anthropic.com>
---
.../transport/http/util/http_transport_utils.c | 12 +++----
util/src/property.c | 42 ++++++++++++----------
2 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/src/core/transport/http/util/http_transport_utils.c b/src/core/transport/http/util/http_transport_utils.c
index 5e4558bc7..21f90d7df 100644
--- a/src/core/transport/http/util/http_transport_utils.c
+++ b/src/core/transport/http/util/http_transport_utils.c
@@ -4268,21 +4268,17 @@ axis2_http_transport_utils_session_map_free_void_arg(
const axutil_env_t *env)
{
void *val = NULL;
- const void *key = NULL;
axutil_hash_index_t *hi = NULL;
axutil_hash_t *ht = (axutil_hash_t *)sm_void;
+ /* Free the cookie values stored in the hash. The keys (server names) are
+ * freed by axutil_hash_free() since they were stored with AXIS2_HASH_KEY_STRING
+ * which makes internal copies. */
for(hi = axutil_hash_first(ht, env); hi; hi = axutil_hash_next(env, hi))
{
- axis2_char_t *name = NULL;
axis2_char_t *value = NULL;
- axutil_hash_this(hi, &key, NULL, &val);
- name = (axis2_char_t *) key;
- if(name)
- {
- AXIS2_FREE(env->allocator, name);
- }
+ axutil_hash_this(hi, NULL, NULL, &val);
value = (axis2_char_t *) val;
if(value)
{
diff --git a/util/src/property.c b/util/src/property.c
index a544ce425..0a25615be 100644
--- a/util/src/property.c
+++ b/util/src/property.c
@@ -87,16 +87,19 @@ axutil_property_free(
if(property->value)
{
- if(property->scope != AXIS2_SCOPE_APPLICATION)
+ /*
+ * Always free owned value regardless of scope. The scope controls property
+ * lifetime within a context (whether it persists across requests), not
+ * whether the value should be freed during cleanup or replacement.
+ * The previous check for AXIS2_SCOPE_APPLICATION caused memory leaks.
+ */
+ if(property->free_func && property->own_value)
{
- if(property->free_func && property->own_value)
- {
- property->free_func(property->value, env);
- }
- else if(property->own_value)
- {
- AXIS2_FREE(env->allocator, property->value);
- }
+ property->free_func(property->value, env);
+ }
+ else if(property->own_value)
+ {
+ AXIS2_FREE(env->allocator, property->value);
}
}
@@ -142,16 +145,19 @@ axutil_property_set_value(
if(property->value)
{
- if(property->scope != AXIS2_SCOPE_APPLICATION)
+ /*
+ * Always free owned value regardless of scope. The scope controls property
+ * lifetime within a context (whether it persists across requests), not
+ * whether the value should be freed during cleanup or replacement.
+ * The previous check for AXIS2_SCOPE_APPLICATION caused memory leaks.
+ */
+ if(property->free_func && property->own_value)
+ {
+ property->free_func(property->value, env);
+ }
+ else if(property->own_value)
{
- if(property->free_func && property->own_value)
- {
- property->free_func(property->value, env);
- }
- else if(property->own_value)
- {
- AXIS2_FREE(env->allocator, property->value);
- }
+ AXIS2_FREE(env->allocator, property->value);
}
}