summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2017-01-30 21:46:03 -0800
committerArseny Kapoulkine <arseny.kapoulkine@gmail.com>2017-01-30 21:58:53 -0800
commit1a2e4b88ee091613d2978fb2d23ce146416d3413 (patch)
treeb1c24355b5caf7e03747970f86e13f48e28271d0 /src
parentac150d504e0e1fa54eb042325c87f08740f1d4f6 (diff)
XPath: Use nonthrowing allocations in duplicate_string
This requires explicit error handling for xpath_string::data calls.
Diffstat (limited to 'src')
-rw-r--r--src/pugixml.cpp23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 2e25551..56cd941 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -7625,8 +7625,8 @@ PUGI__NS_BEGIN
static char_t* duplicate_string(const char_t* string, size_t length, xpath_allocator* alloc)
{
- char_t* result = static_cast<char_t*>(alloc->allocate_throw((length + 1) * sizeof(char_t)));
- assert(result);
+ char_t* result = static_cast<char_t*>(alloc->allocate_nothrow((length + 1) * sizeof(char_t)));
+ if (!result) return 0;
memcpy(result, string, length * sizeof(char_t));
result[length] = 0;
@@ -7655,9 +7655,13 @@ PUGI__NS_BEGIN
{
assert(begin <= end);
+ if (begin == end)
+ return xpath_string();
+
size_t length = static_cast<size_t>(end - begin);
+ const char_t* data = duplicate_string(begin, length, alloc);
- return length == 0 ? xpath_string() : xpath_string(duplicate_string(begin, length, alloc), true, length);
+ return data ? xpath_string(data, true, length) : xpath_string();
}
xpath_string(): _buffer(PUGIXML_TEXT("")), _uses_heap(false), _length_heap(0)
@@ -7715,8 +7719,11 @@ PUGI__NS_BEGIN
if (!_uses_heap)
{
size_t length_ = strlength(_buffer);
+ const char_t* data_ = duplicate_string(_buffer, length_, alloc);
+
+ if (!data_) return 0;
- _buffer = duplicate_string(_buffer, length_, alloc);
+ _buffer = data_;
_uses_heap = true;
_length_heap = length_;
}
@@ -10595,6 +10602,8 @@ PUGI__NS_BEGIN
xpath_string s = string_value(c.n, stack.result);
char_t* begin = s.data(stack.result);
+ if (!begin) return xpath_string();
+
char_t* end = normalize_space(begin);
return xpath_string::from_heap_preallocated(begin, end);
@@ -10605,6 +10614,8 @@ PUGI__NS_BEGIN
xpath_string s = _left->eval_string(c, stack);
char_t* begin = s.data(stack.result);
+ if (!begin) return xpath_string();
+
char_t* end = normalize_space(begin);
return xpath_string::from_heap_preallocated(begin, end);
@@ -10621,6 +10632,8 @@ PUGI__NS_BEGIN
xpath_string to = _right->_next->eval_string(c, swapped_stack);
char_t* begin = s.data(stack.result);
+ if (!begin) return xpath_string();
+
char_t* end = translate(begin, from.c_str(), to.c_str(), to.length());
return xpath_string::from_heap_preallocated(begin, end);
@@ -10631,6 +10644,8 @@ PUGI__NS_BEGIN
xpath_string s = _left->eval_string(c, stack);
char_t* begin = s.data(stack.result);
+ if (!begin) return xpath_string();
+
char_t* end = translate_table(begin, _data.table);
return xpath_string::from_heap_preallocated(begin, end);