From 635fe028015c6091a7765e1c1d23c7512fb3f64e Mon Sep 17 00:00:00 2001
From: Arseny Kapoulkine <arseny.kapoulkine@gmail.com>
Date: Sun, 29 Jan 2017 21:58:12 -0800
Subject: [PATCH] XPath: Provide non-throwing and throwing allocations in
 xpath_allocator

For both allocate and reallocate, provide both _nothrow and _throw
functions; this change renames allocate() to allocate_throw() (same for
reallocate) to make it easier to change the code to remove throwing
variants.
---
 src/pugixml.cpp | 71 ++++++++++++++++++++++++++++++-------------------
 1 file changed, 44 insertions(+), 27 deletions(-)

diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index f52d236c..6b9fc894 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -7442,24 +7442,7 @@ PUGI__NS_BEGIN
 			}
 		}
 
-		void* allocate(size_t size)
-		{
-			void* result = allocate_nothrow(size);
-
-			if (!result)
-			{
-			#ifdef PUGIXML_NO_EXCEPTIONS
-				assert(error_handler);
-				longjmp(*error_handler, 1);
-			#else
-				throw std::bad_alloc();
-			#endif
-			}
-
-			return result;
-		}
-
-		void* reallocate(void* ptr, size_t old_size, size_t new_size)
+		void* reallocate_nothrow(void* ptr, size_t old_size, size_t new_size)
 		{
 			// round size up to block alignment boundary
 			old_size = (old_size + xpath_memory_block_alignment - 1) & ~(xpath_memory_block_alignment - 1);
@@ -7474,8 +7457,8 @@ PUGI__NS_BEGIN
 			if (ptr) _root_size -= old_size;
 
 			// allocate a new version (this will obviously reuse the memory if possible)
-			void* result = allocate(new_size);
-			assert(result);
+			void* result = allocate_nothrow(new_size);
+			if (!result) return 0;
 
 			// we have a new block
 			if (result != ptr && ptr)
@@ -7504,6 +7487,40 @@ PUGI__NS_BEGIN
 			return result;
 		}
 
+		void* allocate_throw(size_t size)
+		{
+			void* result = allocate_nothrow(size);
+
+			if (!result)
+			{
+			#ifdef PUGIXML_NO_EXCEPTIONS
+				assert(error_handler);
+				longjmp(*error_handler, 1);
+			#else
+				throw std::bad_alloc();
+			#endif
+			}
+
+			return result;
+		}
+
+		void* reallocate_throw(void* ptr, size_t old_size, size_t new_size)
+		{
+			void* result = reallocate_nothrow(ptr, old_size, new_size);
+
+			if (!result)
+			{
+			#ifdef PUGIXML_NO_EXCEPTIONS
+				assert(error_handler);
+				longjmp(*error_handler, 1);
+			#else
+				throw std::bad_alloc();
+			#endif
+			}
+
+			return result;
+		}
+
 		void revert(const xpath_allocator& state)
 		{
 			// free all new pages
@@ -7602,7 +7619,7 @@ 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((length + 1) * sizeof(char_t)));
+			char_t* result = static_cast<char_t*>(alloc->allocate_throw((length + 1) * sizeof(char_t)));
 			assert(result);
 
 			memcpy(result, string, length * sizeof(char_t));
@@ -7659,7 +7676,7 @@ PUGI__NS_BEGIN
 				size_t result_length = target_length + source_length;
 
 				// allocate new buffer
-				char_t* result = static_cast<char_t*>(alloc->reallocate(_uses_heap ? const_cast<char_t*>(_buffer) : 0, (target_length + 1) * sizeof(char_t), (result_length + 1) * sizeof(char_t)));
+				char_t* result = static_cast<char_t*>(alloc->reallocate_throw(_uses_heap ? const_cast<char_t*>(_buffer) : 0, (target_length + 1) * sizeof(char_t), (result_length + 1) * sizeof(char_t)));
 				assert(result);
 
 				// append first string to the new buffer in case there was no reallocation
@@ -8116,7 +8133,7 @@ PUGI__NS_BEGIN
 
 		// allocate a buffer of suitable length for the number
 		size_t result_size = strlen(mantissa_buffer) + (exponent > 0 ? exponent : -exponent) + 4;
-		char_t* result = static_cast<char_t*>(alloc->allocate(sizeof(char_t) * result_size));
+		char_t* result = static_cast<char_t*>(alloc->allocate_throw(sizeof(char_t) * result_size));
 		assert(result);
 
 		// make the number!
@@ -8748,7 +8765,7 @@ PUGI__NS_BEGIN
 			if (size_ + count > capacity)
 			{
 				// reallocate the old array or allocate a new one
-				xpath_node* data = static_cast<xpath_node*>(alloc->reallocate(_begin, capacity * sizeof(xpath_node), (size_ + count) * sizeof(xpath_node)));
+				xpath_node* data = static_cast<xpath_node*>(alloc->reallocate_throw(_begin, capacity * sizeof(xpath_node), (size_ + count) * sizeof(xpath_node)));
 				assert(data);
 
 				// finalize
@@ -8800,7 +8817,7 @@ PUGI__NS_BEGIN
 		size_t new_capacity = capacity + capacity / 2 + 1;
 
 		// reallocate the old array or allocate a new one
-		xpath_node* data = static_cast<xpath_node*>(alloc->reallocate(_begin, capacity * sizeof(xpath_node), new_capacity * sizeof(xpath_node)));
+		xpath_node* data = static_cast<xpath_node*>(alloc->reallocate_throw(_begin, capacity * sizeof(xpath_node), new_capacity * sizeof(xpath_node)));
 		assert(data);
 
 		// finalize
@@ -10386,7 +10403,7 @@ PUGI__NS_BEGIN
 			// allocate on-heap for large concats
 			if (count > sizeof(static_buffer) / sizeof(static_buffer[0]))
 			{
-				buffer = static_cast<xpath_string*>(stack.temp->allocate(count * sizeof(xpath_string)));
+				buffer = static_cast<xpath_string*>(stack.temp->allocate_throw(count * sizeof(xpath_string)));
 				assert(buffer);
 			}
 
@@ -10404,7 +10421,7 @@ PUGI__NS_BEGIN
 			for (size_t i = 0; i < count; ++i) length += buffer[i].length();
 
 			// create final string
-			char_t* result = static_cast<char_t*>(stack.result->allocate((length + 1) * sizeof(char_t)));
+			char_t* result = static_cast<char_t*>(stack.result->allocate_throw((length + 1) * sizeof(char_t)));
 			assert(result);
 
 			char_t* ri = result;
-- 
GitLab