summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2017-01-31 19:19:04 -0800
committerArseny Kapoulkine <arseny.kapoulkine@gmail.com>2017-01-31 19:19:04 -0800
commit094a0c8ebe44a1bfeb8575b33138a8b258bf8f4b (patch)
tree22a20d927f0f18c0fcff1bc4808fc27594bf00d0
parent41fb880bf0c3246df50103c6ef3cf91d0fd5eefc (diff)
tests: Add compact hash table reserve test
This makes sure all .reserve calls failure paths are covered. These tests don't explicitly test if reserve is present on all paths - this is much harder to test since not all modifications require reserve to be called, so we'll have to rely on a combination of automated testing and sanity checking for this. Also add more parsing out of memory coverage tests.
-rw-r--r--tests/test_compact.cpp110
-rw-r--r--tests/test_parse.cpp13
2 files changed, 122 insertions, 1 deletions
diff --git a/tests/test_compact.cpp b/tests/test_compact.cpp
new file mode 100644
index 0000000..7c90d07
--- /dev/null
+++ b/tests/test_compact.cpp
@@ -0,0 +1,110 @@
+#ifdef PUGIXML_COMPACT
+#include "common.hpp"
+
+static void overflow_hash_table(xml_document& doc)
+{
+ xml_node n = doc.child(STR("n"));
+
+ // compact encoding assumes next_sibling is a forward-only pointer so we can allocate hash entries by reordering nodes
+ // we allocate enough hash entries to be exactly on the edge of rehash threshold
+ for (int i = 0; i < 8; ++i)
+ CHECK(n.prepend_child(node_element));
+}
+
+TEST_XML(compact_out_of_memory_string, "<n/>")
+{
+ test_runner::_memory_fail_threshold = 1;
+
+ overflow_hash_table(doc);
+
+ xml_node n = doc.child(STR("n"));
+
+ CHECK_ALLOC_FAIL(CHECK(!n.set_name(STR("name"))));
+}
+
+TEST_XML(compact_out_of_memory_attribute, "<n a='v'/>")
+{
+ test_runner::_memory_fail_threshold = 1;
+
+ overflow_hash_table(doc);
+
+ xml_node n = doc.child(STR("n"));
+ xml_attribute a = n.attribute(STR("a"));
+
+ CHECK_ALLOC_FAIL(CHECK(!n.append_attribute(STR(""))));
+ CHECK_ALLOC_FAIL(CHECK(!n.prepend_attribute(STR(""))));
+ CHECK_ALLOC_FAIL(CHECK(!n.insert_attribute_after(STR(""), a)));
+ CHECK_ALLOC_FAIL(CHECK(!n.insert_attribute_before(STR(""), a)));
+}
+
+TEST_XML(compact_out_of_memory_attribute_copy, "<n a='v'/>")
+{
+ test_runner::_memory_fail_threshold = 1;
+
+ overflow_hash_table(doc);
+
+ xml_node n = doc.child(STR("n"));
+ xml_attribute a = n.attribute(STR("a"));
+
+ CHECK_ALLOC_FAIL(CHECK(!n.append_copy(a)));
+ CHECK_ALLOC_FAIL(CHECK(!n.prepend_copy(a)));
+ CHECK_ALLOC_FAIL(CHECK(!n.insert_copy_after(a, a)));
+ CHECK_ALLOC_FAIL(CHECK(!n.insert_copy_before(a, a)));
+}
+
+TEST_XML(compact_out_of_memory_node, "<n/>")
+{
+ test_runner::_memory_fail_threshold = 1;
+
+ overflow_hash_table(doc);
+
+ xml_node n = doc.child(STR("n"));
+
+ CHECK_ALLOC_FAIL(CHECK(!doc.append_child(node_element)));
+ CHECK_ALLOC_FAIL(CHECK(!doc.prepend_child(node_element)));
+ CHECK_ALLOC_FAIL(CHECK(!doc.insert_child_after(node_element, n)));
+ CHECK_ALLOC_FAIL(CHECK(!doc.insert_child_before(node_element, n)));
+}
+
+TEST_XML(compact_out_of_memory_node_copy, "<n/>")
+{
+ test_runner::_memory_fail_threshold = 1;
+
+ overflow_hash_table(doc);
+
+ xml_node n = doc.child(STR("n"));
+
+ CHECK_ALLOC_FAIL(CHECK(!doc.append_copy(n)));
+ CHECK_ALLOC_FAIL(CHECK(!doc.prepend_copy(n)));
+ CHECK_ALLOC_FAIL(CHECK(!doc.insert_copy_after(n, n)));
+ CHECK_ALLOC_FAIL(CHECK(!doc.insert_copy_before(n, n)));
+}
+
+TEST_XML(compact_out_of_memory_node_move, "<n/><ne/>")
+{
+ test_runner::_memory_fail_threshold = 1;
+
+ overflow_hash_table(doc);
+
+ xml_node n = doc.child(STR("n"));
+ xml_node ne = doc.child(STR("ne"));
+
+ CHECK_ALLOC_FAIL(CHECK(!doc.append_move(n)));
+ CHECK_ALLOC_FAIL(CHECK(!doc.prepend_move(n)));
+ CHECK_ALLOC_FAIL(CHECK(!doc.insert_move_after(n, ne)));
+ CHECK_ALLOC_FAIL(CHECK(!doc.insert_move_before(n, ne)));
+}
+
+TEST_XML(compact_out_of_memory_remove, "<n a='v'/>")
+{
+ test_runner::_memory_fail_threshold = 1;
+
+ overflow_hash_table(doc);
+
+ xml_node n = doc.child(STR("n"));
+ xml_attribute a = n.attribute(STR("a"));
+
+ CHECK_ALLOC_FAIL(CHECK(!n.remove_attribute(a)));
+ CHECK_ALLOC_FAIL(CHECK(!doc.remove_child(n)));
+}
+#endif
diff --git a/tests/test_parse.cpp b/tests/test_parse.cpp
index f94a565..fa9555d 100644
--- a/tests/test_parse.cpp
+++ b/tests/test_parse.cpp
@@ -928,13 +928,24 @@ TEST(parse_out_of_memory_halfway_attr)
TEST(parse_out_of_memory_conversion)
{
- test_runner::_memory_fail_threshold = 256;
+ test_runner::_memory_fail_threshold = 1;
xml_document doc;
CHECK_ALLOC_FAIL(CHECK(doc.load_buffer("<foo\x90/>", 7, parse_default, encoding_latin1).status == status_out_of_memory));
CHECK(!doc.first_child());
}
+#ifdef PUGIXML_WCHAR_MODE
+TEST(parse_out_of_memory_conversion_wchar)
+{
+ test_runner::_memory_fail_threshold = 1;
+
+ xml_document doc;
+ CHECK_ALLOC_FAIL(CHECK(doc.load_buffer("<foo />", 7).status == status_out_of_memory));
+ CHECK(!doc.first_child());
+}
+#endif
+
TEST(parse_out_of_memory_allocator_state_sync)
{
const unsigned int count = 10000;