|
|
@ -27,17 +27,16 @@ namespace grpc { |
|
|
|
|
|
|
|
|
|
|
|
namespace internal { |
|
|
|
namespace internal { |
|
|
|
|
|
|
|
|
|
|
|
// Provide access to GrpcProtoBufferWriter internals.
|
|
|
|
// Provide access to ProtoBufferWriter internals.
|
|
|
|
class GrpcProtoBufferWriterPeer { |
|
|
|
class ProtoBufferWriterPeer { |
|
|
|
public: |
|
|
|
public: |
|
|
|
explicit GrpcProtoBufferWriterPeer(GrpcProtoBufferWriter* writer) |
|
|
|
explicit ProtoBufferWriterPeer(ProtoBufferWriter* writer) : writer_(writer) {} |
|
|
|
: writer_(writer) {} |
|
|
|
|
|
|
|
bool have_backup() const { return writer_->have_backup_; } |
|
|
|
bool have_backup() const { return writer_->have_backup_; } |
|
|
|
const grpc_slice& backup_slice() const { return writer_->backup_slice_; } |
|
|
|
const grpc_slice& backup_slice() const { return writer_->backup_slice_; } |
|
|
|
const grpc_slice& slice() const { return writer_->slice_; } |
|
|
|
const grpc_slice& slice() const { return writer_->slice_; } |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
private: |
|
|
|
GrpcProtoBufferWriter* writer_; |
|
|
|
ProtoBufferWriter* writer_; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// Provide access to ByteBuffer internals.
|
|
|
|
// Provide access to ByteBuffer internals.
|
|
|
@ -53,14 +52,14 @@ class GrpcByteBufferPeer { |
|
|
|
class ProtoUtilsTest : public ::testing::Test {}; |
|
|
|
class ProtoUtilsTest : public ::testing::Test {}; |
|
|
|
|
|
|
|
|
|
|
|
// Regression test for a memory corruption bug where a series of
|
|
|
|
// Regression test for a memory corruption bug where a series of
|
|
|
|
// GrpcProtoBufferWriter Next()/Backup() invocations could result in a dangling
|
|
|
|
// ProtoBufferWriter Next()/Backup() invocations could result in a dangling
|
|
|
|
// pointer returned by Next() due to the interaction between grpc_slice inlining
|
|
|
|
// pointer returned by Next() due to the interaction between grpc_slice inlining
|
|
|
|
// and GRPC_SLICE_START_PTR.
|
|
|
|
// and GRPC_SLICE_START_PTR.
|
|
|
|
TEST_F(ProtoUtilsTest, TinyBackupThenNext) { |
|
|
|
TEST_F(ProtoUtilsTest, TinyBackupThenNext) { |
|
|
|
ByteBuffer bp; |
|
|
|
ByteBuffer bp; |
|
|
|
const int block_size = 1024; |
|
|
|
const int block_size = 1024; |
|
|
|
GrpcProtoBufferWriter writer(&bp, block_size, 8192); |
|
|
|
ProtoBufferWriter writer(&bp, block_size, 8192); |
|
|
|
GrpcProtoBufferWriterPeer peer(&writer); |
|
|
|
ProtoBufferWriterPeer peer(&writer); |
|
|
|
|
|
|
|
|
|
|
|
void* data; |
|
|
|
void* data; |
|
|
|
int size; |
|
|
|
int size; |
|
|
@ -81,7 +80,7 @@ namespace { |
|
|
|
// Set backup_size to 0 to indicate no backup is needed.
|
|
|
|
// Set backup_size to 0 to indicate no backup is needed.
|
|
|
|
void BufferWriterTest(int block_size, int total_size, int backup_size) { |
|
|
|
void BufferWriterTest(int block_size, int total_size, int backup_size) { |
|
|
|
ByteBuffer bb; |
|
|
|
ByteBuffer bb; |
|
|
|
GrpcProtoBufferWriter writer(&bb, block_size, total_size); |
|
|
|
ProtoBufferWriter writer(&bb, block_size, total_size); |
|
|
|
|
|
|
|
|
|
|
|
int written_size = 0; |
|
|
|
int written_size = 0; |
|
|
|
void* data; |
|
|
|
void* data; |
|
|
@ -162,7 +161,7 @@ TEST(WriterTest, LargeBlockLargeBackup) { BufferWriterTest(4096, 8192, 4095); } |
|
|
|
} // namespace grpc
|
|
|
|
} // namespace grpc
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char** argv) { |
|
|
|
int main(int argc, char** argv) { |
|
|
|
// Ensure the GrpcProtoBufferWriter internals are initialized.
|
|
|
|
// Ensure the ProtoBufferWriter internals are initialized.
|
|
|
|
grpc::internal::GrpcLibraryInitializer init; |
|
|
|
grpc::internal::GrpcLibraryInitializer init; |
|
|
|
init.summon(); |
|
|
|
init.summon(); |
|
|
|
grpc::GrpcLibraryCodegen lib; |
|
|
|
grpc::GrpcLibraryCodegen lib; |
|
|
|