diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-07-20 16:49:50 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-07-20 16:49:50 +0300 |
commit | 81d07acbbfbc7ebb897edef9aa7c1b2f24272ae4 (patch) | |
tree | 9fd68f0dff5dde8a0108e906e61ab037ec98224a | |
parent | 5c69f2148d7aee85140403fa9346ffaf9532a3fe (diff) | |
download | mailutils-81d07acbbfbc7ebb897edef9aa7c1b2f24272ae4.tar.gz mailutils-81d07acbbfbc7ebb897edef9aa7c1b2f24272ae4.tar.bz2 |
Fix memory leak in property code
The property API contains a serious flaw that leads to memory leaks.
The property initialization function (set by mu_property_set_init or
similiar functions) is supposed to initialize the supported methods
in mu_property_t, in particular _prop_done, which is responsible for
releasing the resources allocated for the initdata object upon
invocation of mu_property_destroy.
However, the initialization function gets called only upon a read/write
manipulation on the property. This means that unless at least one
such operation is performed the _prop_done method will not be initialized
and the resources (if any) allocated for the initial data object will
never be released. This is true, in particular for the MH properties
and assoc properties with I/O stream.
Until the API is revamped, the following solution is implemented.
The function mu_property_create_init calls the mu_property_init
function if called with a non-NULL third argument (initdata).
This ensures that it will be properly freed upon destroying the
object.
The use of low-level functions mu_property_set_init and
mu_property_set_init_data requires the caller to call mu_property_init
explicitly, if needed.
* include/mailutils/property.h (mu_property_init): New proto.
* libmailutils/property/create.c (_mu_property_init): Rename to
mu_property_init.
(mu_property_create_init): Call mu_property_init if initdata is not
NULL.
* libmailutils/property/propinv.c: Update call to mu_property_init.
-rw-r--r-- | include/mailutils/property.h | 1 | ||||
-rw-r--r-- | libmailutils/property/create.c | 10 | ||||
-rw-r--r-- | libmailutils/property/propinv.c | 2 |
3 files changed, 10 insertions, 3 deletions
diff --git a/include/mailutils/property.h b/include/mailutils/property.h index ad1aed5a5..25334d384 100644 --- a/include/mailutils/property.h +++ b/include/mailutils/property.h @@ -35,6 +35,7 @@ int mu_property_set_init_data (mu_property_t prop, void *data, void **old_data); void mu_property_destroy (mu_property_t *pprop); +int mu_property_init (mu_property_t prop); void mu_property_ref (mu_property_t prop); void mu_property_unref (mu_property_t prop); int mu_property_save (mu_property_t prop); diff --git a/libmailutils/property/create.c b/libmailutils/property/create.c index 4b053e333..b30a42a3d 100644 --- a/libmailutils/property/create.c +++ b/libmailutils/property/create.c @@ -42,6 +42,12 @@ mu_property_create_init (mu_property_t *pprop, if (rc == 0) { mu_property_set_init (prop, initfun, initdata); + if (initdata) + { + rc = mu_property_init (prop); + if (rc) + return rc; + } *pprop = prop; } return rc; @@ -122,7 +128,7 @@ mu_property_save (mu_property_t prop) } int -_mu_property_init (mu_property_t prop) +mu_property_init (mu_property_t prop) { int rc = 0; if (!(prop->_prop_flags & MU_PROP_INIT)) @@ -156,7 +162,7 @@ _mu_property_check (mu_property_t prop) if (!prop) return EINVAL; - rc = _mu_property_init (prop); + rc = mu_property_init (prop); if (rc == 0) rc = _mu_property_fill (prop); return rc; diff --git a/libmailutils/property/propinv.c b/libmailutils/property/propinv.c index 5b69c7b2c..0a7e3ae67 100644 --- a/libmailutils/property/propinv.c +++ b/libmailutils/property/propinv.c @@ -30,7 +30,7 @@ mu_property_invalidate (mu_property_t prop) if (!prop) return EINVAL; - rc = _mu_property_init (prop); + rc = mu_property_init (prop); if (rc) return rc; if (prop->_prop_flags & MU_PROP_FILL) |