lslebodn / rpms / ding-libs

Forked from rpms/ding-libs 6 years ago
Clone
Blob Blame History Raw
From a1e11a21897b18addb8cf428f8afee4e95841327 Mon Sep 17 00:00:00 2001
From: Alexander Scheel <ascheel@redhat.com>
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 <mzidek@redhat.com>
(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