From a1e11a21897b18addb8cf428f8afee4e95841327 Mon Sep 17 00:00:00 2001 From: Alexander Scheel Date: Wed, 12 Jul 2017 16:21:40 -0400 Subject: [PATCH] INI: Prevent null return_cfg during augment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the behavior of ini_config_augment so that result_cfg will not be null unless out of memory. In particular, when base_cfg is non-NULL and a fatal error occurred, result_cfg will now be a copy of base_cfg. This reflects existing documentation, as base_cfg will be augmented and result_cfg is the result of the merge. Resolves: https://pagure.io/SSSD/ding-libs/issue/2776 Reviewed-by: Michal Židek (cherry picked from commit 42cf1e061fc807b9d65a1003c1db1f0f3bebc7d7) --- ini/ini_augment.c | 55 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/ini/ini_augment.c b/ini/ini_augment.c index ea3d3da..8e57c6a 100644 --- a/ini/ini_augment.c +++ b/ini/ini_augment.c @@ -679,27 +679,28 @@ static int ini_aug_apply(struct ini_cfgobj *cfg, TRACE_FLOW_ENTRY(); - len = ref_array_len(ra_list); - if (len == 0) { - /* List is empty - nothing to do */ - *out_cfg = NULL; - TRACE_FLOW_EXIT(); - return EOK; - } - error = ini_config_copy(cfg, &res_cfg); if (error) { TRACE_ERROR_NUMBER("Failed to copy config object", error); + *out_cfg = NULL; return error; } + len = ref_array_len(ra_list); + if (len == 0) { + /* List is empty - nothing to do */ + *out_cfg = res_cfg; + TRACE_FLOW_EXIT(); + return EOK; + } + /* Prepare patterns */ error = ini_aug_regex_prepare(sections, ra_err, &ra_regex); if (error) { TRACE_ERROR_NUMBER("Failed to prepare regex array.", error); - ini_config_destroy(res_cfg); + *out_cfg = res_cfg; return error; } @@ -710,9 +711,7 @@ static int ini_aug_apply(struct ini_cfgobj *cfg, error = ini_config_create(&snip_cfg); if (error) { TRACE_ERROR_NUMBER("Failed to create config object", error); - ini_config_destroy(res_cfg); - ref_array_destroy(ra_regex); - return error; + goto err; } /* Process snippet */ @@ -762,9 +761,7 @@ static int ini_aug_apply(struct ini_cfgobj *cfg, if (error) { TRACE_ERROR_NUMBER("Can't get errors.", error); ini_config_destroy(snip_cfg); - ini_config_destroy(res_cfg); - ref_array_destroy(ra_regex); - return error; + goto err; } /* Copy errors into error array */ @@ -795,9 +792,7 @@ static int ini_aug_apply(struct ini_cfgobj *cfg, if (error) { TRACE_ERROR_NUMBER("Failed to validate section.", error); ini_config_destroy(snip_cfg); - ini_config_destroy(res_cfg); - ref_array_destroy(ra_regex); - return error; + goto err; } } @@ -809,9 +804,7 @@ static int ini_aug_apply(struct ini_cfgobj *cfg, if (error == ENOMEM) { TRACE_ERROR_NUMBER("Merge failed.", error); ini_config_destroy(snip_cfg); - ini_config_destroy(res_cfg); - ref_array_destroy(ra_regex); - return error; + goto err; } else if ((error == EEXIST) && @@ -849,6 +842,20 @@ static int ini_aug_apply(struct ini_cfgobj *cfg, *out_cfg = res_cfg; TRACE_FLOW_EXIT(); return error; + +err: + ini_config_destroy(res_cfg); + ref_array_destroy(ra_regex); + + if (ini_config_copy(cfg, &res_cfg)) { + TRACE_ERROR_NUMBER("Failed to copy config object", error); + *out_cfg = NULL; + return error; + } + + *out_cfg = res_cfg; + + return error; } /* Function to merge additional snippets of the config file @@ -874,8 +881,6 @@ int ini_config_augment(struct ini_cfgobj *base_cfg, struct ref_array *ra_err = NULL; /* List of files that were merged */ struct ref_array *ra_ok = NULL; - /* Resulting configuration object */ - struct ini_cfgobj *out_cfg = NULL; /* Check arguments */ if (base_cfg == NULL) { @@ -938,7 +943,7 @@ int ini_config_augment(struct ini_cfgobj *base_cfg, merge_flags, ra_err, ra_ok, - &out_cfg); + result_cfg); if (error) { TRACE_ERROR_NUMBER("Failed to process snippet list.", error); @@ -951,8 +956,6 @@ int ini_config_augment(struct ini_cfgobj *base_cfg, /* Cleanup */ ref_array_destroy(ra_list); - *result_cfg = out_cfg; - if (error_list) { *error_list = ra_err; } -- 2.13.2