From 4334416f6f911c139558813b0eb68b94e0024b75 Mon Sep 17 00:00:00 2001 From: Christopher Warrington Date: Mon, 30 Oct 2017 16:34:36 -0700 Subject: [PATCH] [c++ grpc] Fix multi-slice deser. memory leak The caller of grpc_byte_buffer_reader_next is responsible for calling grpc_slice_unref on the slice. However, SerializationTraits::Deserialize was only calling grpc_slice_unref on the last slice. Now, it is called on each slice. Also fixes a potential bug that would call grpc_slice_unref on an uninitialized slice. --- CHANGELOG.md | 4 ++++ cpp/inc/bond/ext/grpc/bond_utils.h | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 375651ceff..79f966dd6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ different versioning scheme, following the Haskell community's * C# NuGet version: TBD * C# Comm NuGet version: TBD +### C++ ### +* Fixed a memory leak when deserializing Bond-over-gRPC messages that were + stored as multiple slices. + ## 7.0.1: 2017-10-26 ## * `gbc` & compiler library: 0.10.1.0 * IDL core version: 2.0 diff --git a/cpp/inc/bond/ext/grpc/bond_utils.h b/cpp/inc/bond/ext/grpc/bond_utils.h index a813976714..73eb6be7de 100644 --- a/cpp/inc/bond/ext/grpc/bond_utils.h +++ b/cpp/inc/bond/ext/grpc/bond_utils.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -71,7 +72,7 @@ namespace grpc { boost::shared_ptr buff = boost::make_shared_noinit(bufferSize); - // TODO: exception safety of reader, s, buffer + // TODO: exception safety of reader, buffer grpc_byte_buffer_reader reader; if (!grpc_byte_buffer_reader_init(&reader, buffer)) { @@ -81,16 +82,15 @@ namespace grpc { char* dest = buff.get(); - grpc_slice s; - while (grpc_byte_buffer_reader_next(&reader, &s) != 0) + for (grpc_slice grpc_s; grpc_byte_buffer_reader_next(&reader, &grpc_s) != 0;) { - std::memcpy(dest, GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s)); - dest += GRPC_SLICE_LENGTH(s); + grpc::Slice s{ grpc_s, grpc::Slice::STEAL_REF }; + std::memcpy(dest, s.begin(), s.size()); + dest += s.size(); } BOOST_ASSERT(dest == buff.get() + bufferSize); - grpc_slice_unref(s); grpc_byte_buffer_reader_destroy(&reader); grpc_byte_buffer_destroy(buffer);