summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2014-11-02 09:30:56 +0100
committerArseny Kapoulkine <arseny.kapoulkine@gmail.com>2014-11-02 09:30:56 +0100
commite9948b4b05ca23cb95a6ca75ce4ee840e1fbda9b (patch)
tree798c9638505748dd1adc6313e56a0f80120c243a
parentf68a320a0203279db2e8692cc9e21f71551454e4 (diff)
Fix undefined behavior while calling memcpy
Calling memcpy(x, 0, 0) is technically undefined (although it should usually be a no-op).
-rw-r--r--src/pugixml.cpp6
-rw-r--r--tests/test_dom_modify.cpp13
2 files changed, 18 insertions, 1 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 4b1d5ab..59e8f79 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -1352,7 +1352,11 @@ PUGI__NS_BEGIN
char_t* buffer = static_cast<char_t*>(xml_memory::allocate((length + 1) * sizeof(char_t)));
if (!buffer) return false;
- memcpy(buffer, contents, length * sizeof(char_t));
+ if (contents)
+ memcpy(buffer, contents, length * sizeof(char_t));
+ else
+ assert(length == 0);
+
buffer[length] = 0;
out_buffer = buffer;
diff --git a/tests/test_dom_modify.cpp b/tests/test_dom_modify.cpp
index 07fe6dc..45cf3ea 100644
--- a/tests/test_dom_modify.cpp
+++ b/tests/test_dom_modify.cpp
@@ -1091,6 +1091,19 @@ TEST_XML(dom_node_append_buffer_fragment, "<node />")
CHECK_NODE(doc, STR("<node>1234</node>"));
}
+TEST_XML(dom_node_append_buffer_empty, "<node />")
+{
+ xml_node node = doc.child(STR("node"));
+
+ CHECK(node.append_buffer("", 0).status == status_no_document_element);
+ CHECK(node.append_buffer("", 0, parse_fragment).status == status_ok);
+
+ CHECK(node.append_buffer(0, 0).status == status_no_document_element);
+ CHECK(node.append_buffer(0, 0, parse_fragment).status == status_ok);
+
+ CHECK_NODE(doc, STR("<node />"));
+}
+
TEST_XML(dom_node_prepend_move, "<node>foo<child/></node>")
{
xml_node child = doc.child(STR("node")).child(STR("child"));