From 260dce0953ecfe68dbe33ba1510c8494e19340ea Mon Sep 17 00:00:00 2001
From: Thulinma <jaron@vietors.com>
Date: Tue, 8 Sep 2020 18:36:47 +0200
Subject: [PATCH] Backported some Util::ResizeablePointer improvements from 3.0

---
 lib/util.cpp | 28 ++++++++++++++++++++++++++++
 lib/util.h   |  6 ++++++
 2 files changed, 34 insertions(+)

diff --git a/lib/util.cpp b/lib/util.cpp
index aec2668a..2a4402dc 100644
--- a/lib/util.cpp
+++ b/lib/util.cpp
@@ -184,13 +184,32 @@ namespace Util{
     return true;
   }
 
+  bool ResizeablePointer::assign(const std::string & str){
+    return assign(str.data(), str.length());
+  }
+
+
   bool ResizeablePointer::append(const void * p, uint32_t l){
+    //We're writing to ourselves or from null pointer - assume outside write (e.g. fread or socket operation) and update the size
+    if (!p || p == ((char*)ptr)+currSize){
+      if (currSize+l > maxSize){
+        FAIL_MSG("Pointer write went beyond allocated size! Memory corruption likely.");
+        BACKTRACE;
+        return false;
+      }
+      currSize += l;
+      return true;
+    }
     if (!allocate(l+currSize)){return false;}
     memcpy(((char*)ptr)+currSize, p, l);
     currSize += l;
     return true;
   }
 
+  bool ResizeablePointer::append(const std::string & str){
+    return append(str.data(), str.length());
+  }
+
   bool ResizeablePointer::allocate(uint32_t l){
     if (l > maxSize){
       void *tmp = realloc(ptr, l);
@@ -204,6 +223,15 @@ namespace Util{
     return true;
   }
 
+  /// Returns amount of space currently reserved for this pointer
+  uint32_t ResizeablePointer::rsize(){
+    return maxSize;
+  }
+
+
+  void ResizeablePointer::truncate(const size_t newLen){
+    if (currSize > newLen){currSize = newLen;}
+  }
 
   /// Redirects stderr to log parser, writes log parser to the old stderr.
   /// Does nothing if the MIST_CONTROL environment variable is set.
diff --git a/lib/util.h b/lib/util.h
index 08d81aaf..1ce47c5c 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -37,10 +37,16 @@ namespace Util{
       ResizeablePointer();
       ~ResizeablePointer();
       inline size_t& size(){return currSize;}
+      inline const size_t size() const{return currSize;}
       bool assign(const void * p, uint32_t l);
+      bool assign(const std::string & str);
       bool append(const void * p, uint32_t l);
+      bool append(const std::string & str);
       bool allocate(uint32_t l);
+      uint32_t rsize();
+      void truncate(const size_t newLen);
       inline operator char*(){return (char*)ptr;}
+      inline operator const char *() const{return (const char *)ptr;}
       inline operator void*(){return ptr;}
     private:
       void * ptr;