Fix memory bug in SnappyNifSink::Append

Previously `SnappyNifSink` assumed that `GetAppendBuffer` was always
called before `Append`. This turned out to be an invalid assumption.
This was definitely in the land of "How did that even work?". The simple
fix is simple.

This also pre-allocates the write buffer to 8192 bytes which just saves
us from the initial re-allocation on first `Append` since we allocated a
zero length buffer initially.


Project: http://git-wip-us.apache.org/repos/asf/couchdb-snappy/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-snappy/commit/2038ad13
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-snappy/tree/2038ad13
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-snappy/diff/2038ad13

Branch: refs/heads/master
Commit: 2038ad13b1d6926468f25adea110028e3c0b4b0c
Parents: 60572a1
Author: Paul J. Davis <[email protected]>
Authored: Tue Oct 16 11:07:58 2018 -0500
Committer: Paul J. Davis <[email protected]>
Committed: Tue Oct 16 11:07:58 2018 -0500

----------------------------------------------------------------------
 c_src/snappy_nif.cc | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-snappy/blob/2038ad13/c_src/snappy_nif.cc
----------------------------------------------------------------------
diff --git a/c_src/snappy_nif.cc b/c_src/snappy_nif.cc
index 0cec923..50e9018 100644
--- a/c_src/snappy_nif.cc
+++ b/c_src/snappy_nif.cc
@@ -43,6 +43,8 @@ class SnappyNifSink : public snappy::Sink
         ErlNifBinary& GetBin();
 
     private:
+        void EnsureSize(size_t append_length);
+
         ErlNifEnv* env;
         ErlNifBinary bin;
         size_t length;
@@ -67,6 +69,7 @@ void
 SnappyNifSink::Append(const char *data, size_t n)
 {
     if(data != (SC_PTR(bin.data) + length)) {
+        EnsureSize(n);
         memcpy(bin.data + length, data, n);
     }
     length += n;
@@ -75,16 +78,7 @@ SnappyNifSink::Append(const char *data, size_t n)
 char*
 SnappyNifSink::GetAppendBuffer(size_t len, char* scratch)
 {
-    size_t sz;
-    
-    if((length + len) > bin.size) {
-        sz = (len * 4) < 8192 ? 8192 : (len * 4);
-
-        if(!enif_realloc_binary_compat(env, &bin, bin.size + sz)) {
-            throw std::bad_alloc();
-        }
-    }
-
+    EnsureSize(len);
     return SC_PTR(bin.data) + length;
 }
 
@@ -100,6 +94,21 @@ SnappyNifSink::GetBin()
 }
 
 
+void
+SnappyNifSink::EnsureSize(size_t append_length)
+{
+    if((length + append_length) > bin.size) {
+        size_t sz = append_length * 4;
+        if(sz < 8192) {
+            sz = 8192;
+        }
+
+        if(!enif_realloc_binary_compat(env, &bin, bin.size + sz)) {
+            throw std::bad_alloc();
+        }
+    }
+}
+
 static inline ERL_NIF_TERM
 make_atom(ErlNifEnv* env, const char* name)
 {

Reply via email to