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) {
