abg-reader: handle empty corpus nodes in xml representation
authorMatthias Maennich <maennich@google.com>
Mon, 13 Jan 2020 10:42:14 +0000 (10:42 +0000)
committerMatthias Maennich <maennich@google.com>
Mon, 20 Jan 2020 12:20:09 +0000 (12:20 +0000)
An abi-corpus might be part of the representation, but might (due to
filters like whitelisting) not contain actual symbols to be considered.
In that case, `abidw` produces an empty abi-corpus node.

Valid ways of representing this in XML are

 -  <abi-corpus path='vmlinux' architecture='elf-arm-aarch64'/>

 -  <abi-corpus path='vmlinux' architecture='elf-arm-aarch64'></abi-corpus>

 -  <abi-corpus path='vmlinux' architecture='elf-arm-aarch64'>
    </abi-corpus>

abg-reader could currently only handle the last format and crashed upon
processing the first two ones. The crash happened due to the XMLNode
having no children, but that was assumed. The last case succeeded so
far as this form actually contains a text node (with the newline
character) as a child.

Fix this by handling the case of a node not having children by exiting
early with an empty node.

* src/abg-reader.cc (read_corpus_from_input): when assigning a
corpus node, assure the node actually has children.
* tests/test-abidiff.cc (main): Add test for variants of empty
xml nodes to the test harness.
* tests/data/test-abidiff/test-empty-corpus-0.xml: Test input
containing an empty xml node that closes immediately.
* tests/data/test-abidiff/test-empty-corpus-0.xml: Test input
containing an empty xml node that closes immediately with a tag.
* tests/data/test-abidiff/test-empty-corpus-0.xml: Test input
containing an empty xml node that closes with a tag on a new line.
* tests/data/test-abidiff/test-empty-corpus-report.txt:
Expected test output (empty abidiff) for diffing xml with itself.
* tests/data/Makefile.am: Add the new test input material above
to source distribution.

Reviewed-by: Dodji Seketeli <dodji@seketeli.org>
Signed-off-by: Matthias Maennich <maennich@google.com>
src/abg-reader.cc
tests/data/Makefile.am
tests/data/test-abidiff/test-empty-corpus-0.xml [new file with mode: 0644]
tests/data/test-abidiff/test-empty-corpus-1.xml [new file with mode: 0644]
tests/data/test-abidiff/test-empty-corpus-2.xml [new file with mode: 0644]
tests/data/test-abidiff/test-empty-corpus-report.txt [new file with mode: 0644]
tests/test-abidiff.cc

index 9a61e3d..30b9abc 100644 (file)
@@ -1867,8 +1867,6 @@ read_corpus_from_input(read_context& ctxt)
        return nil;
 
       call_reader_next = true;
-
-      ctxt.set_corpus_node(node->children);
     }
   else
     {
@@ -1898,10 +1896,13 @@ read_corpus_from_input(read_context& ctxt)
        XML_NODE_GET_ATTRIBUTE(node, "soname");
       if (soname_str)
        corp.set_soname(reinterpret_cast<char*>(soname_str.get()));
-
-      ctxt.set_corpus_node(node->children);
     }
 
+  if (!node->children)
+    return nil;
+
+  ctxt.set_corpus_node(node->children);
+
   corpus& corp = *ctxt.get_corpus();
 
   walk_xml_node_to_map_type_ids(ctxt, node);
index 01679d0..41d9c25 100644 (file)
@@ -84,6 +84,10 @@ test-abidiff/test-PR18791-v1.so.abi     \
 test-abidiff/test-PR24552-report0.txt  \
 test-abidiff/test-PR24552-v0.abi       \
 test-abidiff/test-PR24552-v1.abi       \
+test-abidiff/test-empty-corpus-0.xml           \
+test-abidiff/test-empty-corpus-1.xml           \
+test-abidiff/test-empty-corpus-2.xml           \
+test-abidiff/test-empty-corpus-report.txt      \
 \
 test-abidiff-exit/test1-voffset-change-report0.txt \
 test-abidiff-exit/test1-voffset-change-report1.txt \
diff --git a/tests/data/test-abidiff/test-empty-corpus-0.xml b/tests/data/test-abidiff/test-empty-corpus-0.xml
new file mode 100644 (file)
index 0000000..aa8059b
--- /dev/null
@@ -0,0 +1,3 @@
+<abi-corpus-group architecture='elf-arm-aarch64'>
+  <abi-corpus path='vmlinux' architecture='elf-arm-aarch64'/>
+</abi-corpus-group>
diff --git a/tests/data/test-abidiff/test-empty-corpus-1.xml b/tests/data/test-abidiff/test-empty-corpus-1.xml
new file mode 100644 (file)
index 0000000..6adf18b
--- /dev/null
@@ -0,0 +1,3 @@
+<abi-corpus-group architecture='elf-arm-aarch64'>
+  <abi-corpus path='vmlinux' architecture='elf-arm-aarch64'></abi-corpus>
+</abi-corpus-group>
diff --git a/tests/data/test-abidiff/test-empty-corpus-2.xml b/tests/data/test-abidiff/test-empty-corpus-2.xml
new file mode 100644 (file)
index 0000000..5e025ff
--- /dev/null
@@ -0,0 +1,4 @@
+<abi-corpus-group architecture='elf-arm-aarch64'>
+  <abi-corpus path='vmlinux' architecture='elf-arm-aarch64'>
+  </abi-corpus>
+</abi-corpus-group>
diff --git a/tests/data/test-abidiff/test-empty-corpus-report.txt b/tests/data/test-abidiff/test-empty-corpus-report.txt
new file mode 100644 (file)
index 0000000..a9d032e
--- /dev/null
@@ -0,0 +1,3 @@
+Functions changes summary: 0 Removed, 0 Changed, 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
index d311833..80e9c0a 100644 (file)
@@ -107,6 +107,24 @@ static InOutSpec specs[] =
     "data/test-abidiff/test-PR24552-report0.txt",
     "output/test-abidiff/test-PR24552-report0.txt"
   },
+  {
+    "data/test-abidiff/test-empty-corpus-0.xml",
+    "data/test-abidiff/test-empty-corpus-0.xml",
+    "data/test-abidiff/test-empty-corpus-report.txt",
+    "output/test-abidiff/test-empty-corpus-report.txt"
+  },
+  {
+    "data/test-abidiff/test-empty-corpus-1.xml",
+    "data/test-abidiff/test-empty-corpus-1.xml",
+    "data/test-abidiff/test-empty-corpus-report.txt",
+    "output/test-abidiff/test-empty-corpus-report.txt"
+  },
+  {
+    "data/test-abidiff/test-empty-corpus-2.xml",
+    "data/test-abidiff/test-empty-corpus-2.xml",
+    "data/test-abidiff/test-empty-corpus-report.txt",
+    "output/test-abidiff/test-empty-corpus-report.txt"
+  },
   // This should be the last entry.
   {0, 0, 0, 0}
 };