diff options
author | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2014-10-25 16:37:16 +0000 |
---|---|---|
committer | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2014-10-25 16:37:16 +0000 |
commit | 0b7964917cbfd9d007c8a017eaced636f53ddeb3 (patch) | |
tree | 557a2abed7a5079afe56e40cab15a46b6c468a94 | |
parent | 503abf607a9e1d5d778edb48e00514f5cb73f777 (diff) |
Fix node copying for some out of memory cases
A page can fail to allocate during attribute creation; this case was not
previously handled.
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1080 99668b35-9821-0410-8761-19e4c4f06640
-rw-r--r-- | src/pugixml.cpp | 9 | ||||
-rw-r--r-- | tests/test_dom_modify.cpp | 17 |
2 files changed, 20 insertions, 6 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 1187383..109a635 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -164,6 +164,8 @@ PUGI__NS_BEGIN static deallocation_function deallocate; }; + // Global allocation functions are stored in class statics so that in header mode linker deduplicates them + // Without a template<> we'll get multiple definitions of the same static template <typename T> allocation_function xml_memory_management_function_storage<T>::allocate = default_allocate; template <typename T> deallocation_function xml_memory_management_function_storage<T>::deallocate = default_deallocate; @@ -3735,8 +3737,11 @@ PUGI__NS_BEGIN { xml_attribute_struct* da = append_new_attribute(dn, get_allocator(dn)); - node_copy_string(da->name, da->header, xml_memory_page_name_allocated_mask, sa->name, sa->header, shared_alloc); - node_copy_string(da->value, da->header, xml_memory_page_value_allocated_mask, sa->value, sa->header, shared_alloc); + if (da) + { + node_copy_string(da->name, da->header, xml_memory_page_name_allocated_mask, sa->name, sa->header, shared_alloc); + node_copy_string(da->value, da->header, xml_memory_page_value_allocated_mask, sa->value, sa->header, shared_alloc); + } } } diff --git a/tests/test_dom_modify.cpp b/tests/test_dom_modify.cpp index 01b562a..07fe6dc 100644 --- a/tests/test_dom_modify.cpp +++ b/tests/test_dom_modify.cpp @@ -1361,13 +1361,22 @@ TEST_XML(dom_node_copyless_taint, "<node attr=\"value\" />") CHECK_NODE(doc, STR("<nod1 attr=\"value\" /><node attr=\"valu2\" /><node att3=\"value\" />")); } -TEST_XML(dom_node_copy_out_of_memory, "<node><child1 attr1='value1' attr2='value2' /><child2 /><child3>text1<child4 />text2</child3></node>") +TEST_XML(dom_node_copy_out_of_memory_node, "<node><child1 /><child2 /><child3>text1<child4 />text2</child3></node>") { test_runner::_memory_fail_threshold = 32768 * 2 + 4096; - xml_document copy; - for (int i = 0; i < 100; ++i) - copy.append_copy(doc.first_child()); + xml_document copy; + for (int i = 0; i < 1000; ++i) + copy.append_copy(doc.first_child()); +} + +TEST_XML(dom_node_copy_out_of_memory_attr, "<node attr1='' attr2='' attr3='' attr4='' attr5='' attr6='' attr7='' attr8='' attr9='' attr10='' attr11='' attr12='' attr13='' attr14='' attr15='' />") +{ + test_runner::_memory_fail_threshold = 32768 * 2 + 4096; + + xml_document copy; + for (int i = 0; i < 1000; ++i) + copy.append_copy(doc.first_child()); } TEST_XML(dom_node_remove_deallocate, "<node attr='value'>text</node>") |