Low: libcrmcommon: Fix XML matching when marking changes
Note: the changes in the trace outputs demonstrate a bug in
mark_child_deleted(). I'm not sure why it wasn't appearing before this
fix, but the whole point of this is to be more thorough, after all. I'm
leaving those incorrect outputs and fixing the mark_child_deleted() bug
in a LATER commit, so that the effect is clearer.
match_xml() didn't actually require an exact match. Element matching
behavior depended on whether old XML or new XML was the "haystack". The
signature was as follows, minus types:
match_xml(haystack, needle)
- If needle has an id attribute, then we look for a child of haystack with the same name (element type) that has an id attribute with the same value.
- If needle does not have an id attribute, then we look for a child of haystack with the same name. We ignore the id attribute, if set.
This means the match is asymmetric. Suppose we have the following
old_xml:
<parent>
<child id="some_id"/>
</parent>
and the following new_xml:
<parent>
<child/>
</parent>
Further suppose that old_child and new_child refer to the child elements
in the respective trees above.
Then:
- match_xml(new_xml, old_child) returns NULL, because old_child has an id and there is no child of new_xml with name "child" and the same id.
- match_xml(old_xml, new_child) returns old_child, because new_child has no id, so it is free to match any child of old_xml named "child".
Note that things become even more complicated if there are multiple
children with the same name in old_xml, new_xml, or both. Especially if
some of them move around: match_xml() returns the FIRST matching child.
This may or may not make a practical difference. I wouldn't be surprised
if some ACL scenarios break though, for example.
Now, the matching is symmetric. We iterate over all old children and
new_children, looking for matching comments and for elements with
matching names and IDs. We mark any matches in the private data of both
matching nodes. Then we iterate again, looking for elements with
matching names. We can consider an ID change as an attribute change.
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>