]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
clean up parent/current/frame brace checking
authorAlan T. DeKok <aland@freeradius.org>
Fri, 27 Jun 2025 18:01:44 +0000 (14:01 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 27 Jun 2025 18:02:31 +0000 (14:02 -0400)
so that it works by looking at what it's supposed to be looking at,
and not sort of by accident

src/lib/server/cf_file.c

index 56cf679913ea68a6891100da2178002ee4b950bf..4c50ea286d7d37c932c716a4c8f532468a0d13f3 100644 (file)
@@ -2153,22 +2153,42 @@ static int parse_input(cf_stack_t *stack)
 
        /*
         *      Catch end of a subsection.
+        *
+        *      frame->current is the new thing we just created.
+        *      frame->parent is the parent of the current frame
+        *      frame->at_reference is the original frame->current, before the @reference
+        *      parent is the parent we started with when we started this section.
         */
        if (*ptr == '}') {
                /*
-                *      We're already at the parent section
-                *      which loaded this file.  We cannot go
-                *      back up another level.
+                *      No pushed braces means that we're already in
+                *      the parent section which loaded this file.  We
+                *      cannot go back up another level.
                 *
-                *      This limitation means that we cannot
-                *      put half of a CONF_SECTION in one
-                *      file, and then the second half in
-                *      another file.  That's fine.
+                *      This limitation means that we cannot put half
+                *      of a CONF_SECTION in one file, and then the
+                *      second half in another file.  That's fine.
                 */
-               if (parent == frame->parent) {
+               if (frame->braces == 0) {
                        return parse_error(stack, ptr, "Too many closing braces");
                }
 
+               /*
+                *      Reset the current and parent to the original
+                *      section, before we were parsing the
+                *      @reference.
+                */
+               if (frame->at_reference) {
+                       frame->current = frame->parent = frame->at_reference;
+                       frame->at_reference = NULL;
+
+               } else {
+                       /*
+                        *      Go back up one section, because we can.
+                        */
+                       frame->current = frame->parent = cf_item_to_section(frame->current->item.parent);
+               }
+
                fr_assert(frame->braces > 0);
                frame->braces--;
 
@@ -2180,13 +2200,6 @@ static int parse_input(cf_stack_t *stack)
                 */
                if (!cf_template_merge(parent, parent->template)) return -1;
 
-               if (frame->at_reference) {
-                       frame->current = frame->at_reference;
-                       frame->at_reference = NULL;
-               } else {
-                       frame->current = cf_item_to_section(parent->item.parent);
-               }
-
                ptr++;
                stack->ptr = ptr;
                return 1;
@@ -2544,7 +2557,12 @@ alloc_section:
                        }
                }
 
-               frame->at_reference = frame->current;
+               /*
+                *      We're processing a section.  The @reference is
+                *      OUTSIDE of this section.
+                */
+               fr_assert(frame->current == frame->parent);
+               frame->at_reference = frame->parent;
                name2_token = T_BARE_WORD;
 
                css = cf_section_alloc(parent, parent, value, NULL);