aboutsummaryrefslogtreecommitdiff
path: root/ruby/ext/google/protobuf_c/encode_decode.c
diff options
context:
space:
mode:
authorJon Skeet <skeet@pobox.com>2015-07-16 07:11:40 +0100
committerJon Skeet <skeet@pobox.com>2015-07-16 07:11:40 +0100
commit19cf9d1e0044e18067ac4f444e3d91a5d939e84e (patch)
treeeadc17fc1043b12cccdd5868e775bc540faa9841 /ruby/ext/google/protobuf_c/encode_decode.c
parent385baaa87c52abf5339b0be7dccf8a4131667117 (diff)
parent11002e70c607255cf91fea0f998fe945ca6ddc5e (diff)
downloadprotobuf-19cf9d1e0044e18067ac4f444e3d91a5d939e84e.tar.gz
protobuf-19cf9d1e0044e18067ac4f444e3d91a5d939e84e.tar.bz2
protobuf-19cf9d1e0044e18067ac4f444e3d91a5d939e84e.zip
Merge pull request #606 from jtattermusch/csharp-experimental-merged
Update csharp-experimental with changes from upstream/master
Diffstat (limited to 'ruby/ext/google/protobuf_c/encode_decode.c')
-rw-r--r--ruby/ext/google/protobuf_c/encode_decode.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/ruby/ext/google/protobuf_c/encode_decode.c b/ruby/ext/google/protobuf_c/encode_decode.c
index fe249d45..f789f6d4 100644
--- a/ruby/ext/google/protobuf_c/encode_decode.c
+++ b/ruby/ext/google/protobuf_c/encode_decode.c
@@ -30,6 +30,18 @@
#include "protobuf.h"
+// This function is equivalent to rb_str_cat(), but unlike the real
+// rb_str_cat(), it doesn't leak memory in some versions of Ruby.
+// For more information, see:
+// https://bugs.ruby-lang.org/issues/11328
+VALUE noleak_rb_str_cat(VALUE rb_str, const char *str, long len) {
+ size_t oldlen = RSTRING_LEN(rb_str);
+ rb_str_modify_expand(rb_str, len);
+ char *p = RSTRING_PTR(rb_str);
+ memcpy(p + oldlen, str, len);
+ rb_str_set_len(rb_str, oldlen + len);
+}
+
// -----------------------------------------------------------------------------
// Parsing.
// -----------------------------------------------------------------------------
@@ -164,7 +176,7 @@ static size_t stringdata_handler(void* closure, const void* hd,
const char* str, size_t len,
const upb_bufhandle* handle) {
VALUE rb_str = (VALUE)closure;
- rb_str_cat(rb_str, str, len);
+ noleak_rb_str_cat(rb_str, str, len);
return len;
}