From 094a0c8ebe44a1bfeb8575b33138a8b258bf8f4b Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 31 Jan 2017 19:19:04 -0800 Subject: 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. --- tests/test_compact.cpp | 110 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/test_parse.cpp | 13 +++++- 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 tests/test_compact.cpp 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, "") +{ + 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, "") +{ + 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, "") +{ + 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, "") +{ + 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, "") +{ + 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, "") +{ + 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, "") +{ + 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("", 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("", 7).status == status_out_of_memory)); + CHECK(!doc.first_child()); +} +#endif + TEST(parse_out_of_memory_allocator_state_sync) { const unsigned int count = 10000; -- cgit v1.2.3