krb5 commit: Merge duplicate subsections in profile library

Greg Hudson ghudson at mit.edu
Tue Apr 17 12:50:14 EDT 2018


https://github.com/krb5/krb5/commit/efab9fa5a6d23c486467264e20b58bf5a9c60f0c
commit efab9fa5a6d23c486467264e20b58bf5a9c60f0c
Author: Robbie Harwood <rharwood at redhat.com>
Date:   Tue Apr 10 15:55:41 2018 -0400

    Merge duplicate subsections in profile library
    
    Modify profile_add_node() to return the existing node, rather than
    making a new one, when adding subsection configuration.
    
    This fixes an issue where the first instance of a subsection will hide
    the second instance entirely.  In particular, it was previously
    impossible to split realm-specific configuration across multiple
    config files.
    
    [ghudson at mit.edu: adjusted style, added test case]
    
    ticket: 7863
    tags: pullup
    target_version: 1.16-next
    target_version: 1.15-next

 src/util/profile/prof_test1  |   22 ++++++++++++++++++++++
 src/util/profile/prof_tree.c |   15 +++++++++++----
 src/util/profile/test.ini    |    6 ++++++
 3 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/src/util/profile/prof_test1 b/src/util/profile/prof_test1
index 7e30fc1..7d13c93 100644
--- a/src/util/profile/prof_test1
+++ b/src/util/profile/prof_test1
@@ -341,6 +341,27 @@ proc test9 {} {
     puts "OK: test9: profile_flush_to_file with no changes"
 }
 
+proc test10 {} {
+    global wd verbose
+
+    # Regression test for #7863: multiply-specified subsections should
+    # be merged.
+    set p [profile_init_path $wd/test2.ini]
+    set x [profile_get_values $p {{test section 2} child_section2 child}]
+    if $verbose { puts "Read $x from profile" }
+    if ![string equal $x "slick harry {john\tb } ron"] {
+	puts stderr "Error: test10: Did not get expected merged children."
+	exit 1
+    }
+
+    set x [profile_get_string $p {test section 2} child_section2 chores]
+    if $verbose { puts "Read $x from profile" }
+    if ![string equal $x "cleaning"] {
+	puts stderr "Error: test10: Did not find expected chores."
+	exit 1
+    }
+}
+
 test1
 test2
 test3
@@ -350,5 +371,6 @@ test6
 test7
 test8
 test9
+test10
 
 exit 0
diff --git a/src/util/profile/prof_tree.c b/src/util/profile/prof_tree.c
index 081f688..38aadc4 100644
--- a/src/util/profile/prof_tree.c
+++ b/src/util/profile/prof_tree.c
@@ -9,7 +9,7 @@
  *
  * Each node may represent either a relation or a section header.
  *
- * A section header must have its value field set to 0, and may a one
+ * A section header must have its value field be null, and may have one
  * or more child nodes, pointed to by first_child.
  *
  * A relation has as its value a pointer to allocated memory
@@ -159,15 +159,22 @@ errcode_t profile_add_node(struct profile_node *section, const char *name,
         return PROF_ADD_NOT_SECTION;
 
     /*
-     * Find the place to insert the new node.  We look for the
-     * place *after* the last match of the node name, since
+     * Find the place to insert the new node.  If we are adding a subsection
+     * and already have a subsection with that name, merge them.  Otherwise,
+     * we look for the place *after* the last match of the node name, since
      * order matters.
      */
     for (p=section->first_child, last = 0; p; last = p, p = p->next) {
         int cmp;
         cmp = strcmp(p->name, name);
-        if (cmp > 0)
+        if (cmp > 0) {
             break;
+        } else if (value == NULL && cmp == 0 &&
+                   p->value == NULL && p->deleted != 1) {
+            /* Found duplicate subsection, so don't make a new one. */
+            *ret_node = p;
+            return 0;
+        }
     }
     retval = profile_create_node(name, value, &new);
     if (retval)
diff --git a/src/util/profile/test.ini b/src/util/profile/test.ini
index 23ca896..6622df1 100644
--- a/src/util/profile/test.ini
+++ b/src/util/profile/test.ini
@@ -10,6 +10,12 @@ this is a comment.  Everything up to the first square brace is ignored.
 	}
 	child_section2 = foo
 
+[test section 2]
+	child_section2 = {
+		child = ron
+		chores = cleaning
+	}
+
 [realms]
 ATHENA.MIT.EDU = {
 	server = KERBEROS.MIT.EDU:88


More information about the cvs-krb5 mailing list