Uploaded image for project: 'CFEngine Community'
  1. CFEngine Community
  2. CFE-3806

edit_xml insert_tree promisers that contain a trailing newline cause the end tag for the selected xpath to be removed, resulting in broken xml

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Open
    • Priority: (None)
    • Resolution: Unresolved
    • Affects Version/s: 3.18.0
    • Fix Version/s: None
    • Component/s: Promise type: files
    • Labels:
      None
    • Story Points:
      3

      Description

      If an edit_xml insert_tree is inserted into an xpath, the paths ending tag gets removed which results in broken xml.

      Workaround: Make sure that you don't have a trailing newline in insert_tree promisers.

      Example/reproducer

      I have an xml file that is used by firewalld:

      <?xml version="1.0" encoding="utf-8"?>
      <zone>
        <short>Public</short>
        <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
        <service name="ssh"/>
        <service name="dhcpv6-client"/>
        <service name="cockpit"/>
      </zone>
      

      I made a promise about some rules that should be inside of the /zone path.

       bundle agent __main__
       {
        methods:
            "init";
            "test";
      
      }
      bundle agent init
      {
        files:
            "/tmp/start.xml"
              content => '<zone>
       <short>Public</short>
       <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
       <service name="ssh"/>
       <service name="dhcpv6-client"/>
       <service name="cockpit"/>
       </zone>';
      
            "/tmp/example1.xml"
              copy_from => local_dcp( "/tmp/start.xml" );
      
            "/tmp/example2.xml"
              copy_from => local_dcp( "/tmp/start.xml" );
      }
      bundle agent test
      {
        files:
      
            "/tmp/example1.xml"
              edit_xml => insert_tree_with_trailing_newline("1.1.1.1", "tcp", "9443");
      
            "/tmp/example2.xml"
              edit_xml => insert_tree_without_trailing_newline("1.1.1.1", "tcp", "9443");
      
         reports:
            "$(with)" with => execresult( "/bin/diff -u /tmp/example1.xml /tmp/example2.xml", noshell);
       }
      
       bundle edit_xml insert_tree_with_trailing_newline(source, protocol, port)
       {
          build_xpath:
               "/zone";
      
         insert_tree:
             '<rule family="ipv4">
         <source address="$(source)"/>
         <port protocol="$(protocol)" port="$(port)"/>
       </rule>
      '
               select_xpath => "/zone";
      
       }
      bundle edit_xml insert_tree_without_trailing_newline(source, protocol, port)
      {
        build_xpath:
            "/zone";
      
        insert_tree:
            '<rule family="ipv4">
         <source address="$(source)"/>
         <port protocol="$(protocol)" port="$(port)"/>
       </rule>'
              select_xpath => "/zone";
      }
      
          info: Copied file '/tmp/start.xml' to '/tmp/example1.xml.cfnew' (mode '600')
          info: Backed up '/tmp/example1.xml' as '/tmp/example1.xml.cfsaved'
          info: Moved '/tmp/example1.xml.cfnew' to '/tmp/example1.xml'
          info: Updated '/tmp/example1.xml' from source '/tmp/start.xml' on 'localhost'
          info: Copied file '/tmp/start.xml' to '/tmp/example2.xml.cfnew' (mode '600')
          info: Backed up '/tmp/example2.xml' as '/tmp/example2.xml.cfsaved'
          info: Moved '/tmp/example2.xml.cfnew' to '/tmp/example2.xml'
          info: Updated '/tmp/example2.xml' from source '/tmp/start.xml' on 'localhost'
          info: Built XPath '/zone' in XML document '/tmp/example1.xml'
          info: build_xpath promise '/zone' repaired
          info: Inserted tree '<rule family="ipv4">
         <source address="1.1.1.1"/>
         <port protocol="tcp" port="9443"/>
       </rule>
      ' at XPath '/zone' in XML document '/tmp/example1.xml'
          info: insert_tree promise '<rule family="ipv4">
         <source address="1.1.1.1"/>
         <port protocol="tcp" port="9443"/>
       </rule>
      ' repaired
          info: Edited xml file '/tmp/example1.xml'
          info: Built XPath '/zone' in XML document '/tmp/example2.xml'
          info: build_xpath promise '/zone' repaired
          info: Inserted tree '<rule family="ipv4">
         <source address="1.1.1.1"/>
         <port protocol="tcp" port="9443"/>
       </rule>' at XPath '/zone' in XML document '/tmp/example2.xml'
          info: insert_tree promise '<rule family="ipv4">
         <source address="1.1.1.1"/>
         <port protocol="tcp" port="9443"/>
       </rule>' repaired
          info: Edited xml file '/tmp/example2.xml'
      R: --- /tmp/example1.xml	2021-10-21 13:40:15.544718846 -0500
      +++ /tmp/example2.xml	2021-10-21 13:40:15.544718846 -0500
      @@ -8,5 +8,4 @@
        <rule family="ipv4">
          <source address="1.1.1.1"/>
          <port protocol="tcp" port="9443"/>
      - </rule>
      -
      + </rule></zone>
      

      I think that a trailing new line should not cause the ending tag to be removed.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              Unassigned Unassigned
              Reporter:
              a10042 Nick Anderson
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Dates

                Created:
                Updated: