test for toplevel line after popping nested var
authorPhilipp Gesang <philipp.gesang@intra2net.com>
Fri, 1 Dec 2017 11:16:34 +0000 (12:16 +0100)
committerPhilipp Gesang <philipp.gesang@intra2net.com>
Fri, 1 Dec 2017 11:16:39 +0000 (12:16 +0100)
After reaching the end of a sequence of CNF siblings at nesting
level > 1, the parser crashes because the updated current line
is a toplevel line:

    234  FIREWALL_NETGROUP,1: "i2n"
    235     (234) FIREWALL_NETGROUP_NETWORK,0: ""
    236        (235) FIREWALL_NETGROUP_NETWORK_IP,0: "172.16.1.0"
    237        (235) FIREWALL_NETGROUP_NETWORK_NETMASK,0: "255.255.255.0"
    238  FIREWALL_NETGROUP,2: "drift-extern" # <----------------------------------- boom!
    239     (238) FIREWALL_NETGROUP_NETWORK,0: "drift"
    240        (239) FIREWALL_NETGROUP_NETWORK_IP,0: "172.16.1.85"
    241        (239) FIREWALL_NETGROUP_NETWORK_NETMASK,0: "255.255.255.255"

Fix by testing for parent lines and exiting immediately.

src/cnfvar.py

index 910a8b2..b31f6f3 100644 (file)
@@ -415,7 +415,8 @@ def read_child_line(line):
 
     match = re.match(child_line_pattern, line)
     if match is None:
-        raise MalformedCNF("Syntax error in child line \"\"\"%s\"\"\"" % line)
+        raise MalformedCNF("Syntax error in child line \"\"\"%s\"\"\""
+                           % from_latin1 (line))
     number, parent, varname, instance, data, comment = match.groups()
     return {
         "number"   : marshal_in_number   (number),
@@ -444,10 +445,14 @@ def parse_cnf_children(state, parent):
                 return (state, lines, None)
             if new_parent > parent:
                 # parent is further down in hierarchy -> new level
-                (state, children, new_parent) = parse_cnf_children(
-                    state, new_parent)
+                (state, children, new_parent) = \
+                    parse_cnf_children (state, new_parent)
                 cnf_line["children"] = children
                 current = get(state)
+                new_parent = get_parent(current)
+                if new_parent is None:
+                    # drop stack
+                    return (state, lines, None)
             if new_parent < parent:
                 # parent is further up in hierarchy -> pop level
                 return (state, lines, new_parent)