From 02a085eb458cb0e469fb2b9b21adce261b6735dc Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 31 Jul 2017 13:15:19 -0700 Subject: [PATCH 1/2] Node: fix segfault with incorrect status argument types --- ext/call.cc | 10 ++++-- test/call_test.js | 85 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/ext/call.cc b/ext/call.cc index 71e69040..26095a78 100644 --- a/ext/call.cc +++ b/ext/call.cc @@ -260,7 +260,10 @@ class SendClientCloseOp : public Op { class SendServerStatusOp : public Op { public: - SendServerStatusOp() { grpc_metadata_array_init(&status_metadata); } + SendServerStatusOp() { + details = grpc_empty_slice(); + grpc_metadata_array_init(&status_metadata); + } ~SendServerStatusOp() { grpc_slice_unref(details); DestroyMetadataArray(&status_metadata); @@ -381,7 +384,10 @@ class ReadMessageOp : public Op { class ClientStatusOp : public Op { public: - ClientStatusOp() { grpc_metadata_array_init(&metadata_array); } + ClientStatusOp() { + grpc_metadata_array_init(&metadata_array); + status_details = grpc_empty_slice(); + } ~ClientStatusOp() { grpc_metadata_array_destroy(&metadata_array); diff --git a/test/call_test.js b/test/call_test.js index aebd298e..e19f47be 100644 --- a/test/call_test.js +++ b/test/call_test.js @@ -188,6 +188,91 @@ describe('call', function() { }, TypeError); }); }); + describe('startBatch with message', function() { + it('should fail with non-buffer arguments', function() { + var call = new grpc.Call(channel, 'method', getDeadline(1)); + assert.throws(function() { + var batch = {}; + batch[grpc.opType.SEND_MESSAGE] = null; + call.startBatch(batch, function(){}); + }, TypeError); + assert.throws(function() { + var batch = {}; + batch[grpc.opType.SEND_MESSAGE] = 5; + call.startBatch(batch, function(){}); + }, TypeError); + assert.throws(function() { + var batch = {}; + batch[grpc.opType.SEND_MESSAGE] = 'value'; + call.startBatch(batch, function(){}); + }, TypeError); + }); + }); + describe('startBatch with status', function() { + it('should fail without a code', function() { + var call = new grpc.Call(channel, 'method', getDeadline(1)); + assert.throws(function() { + var batch = {}; + batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { + details: 'details string', + metadata: {} + }; + call.startBatch(batch, function(){}); + }, TypeError); + }); + it('should fail without details', function() { + var call = new grpc.Call(channel, 'method', getDeadline(1)); + assert.throws(function() { + var batch = {}; + batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { + code: 0, + metadata: {} + }; + call.startBatch(batch, function(){}); + }, TypeError); + }); + it('should fail without metadata', function() { + var call = new grpc.Call(channel, 'method', getDeadline(1)); + assert.throws(function() { + var batch = {}; + batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { + code: 0, + details: 'details string' + }; + call.startBatch(batch, function(){}); + }, TypeError); + }); + it('should fail with incorrectly typed arguments', function() { + var call = new grpc.Call(channel, 'method', getDeadline(1)); + assert.throws(function() { + var batch = {}; + batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { + code: 'code string', + details: 'details string', + metadata: {} + }; + call.startBatch(batch, function(){}); + }, TypeError); + assert.throws(function() { + var batch = {}; + batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { + code: 0, + details: 5, + metadata: {} + }; + call.startBatch(batch, function(){}); + }, TypeError); + assert.throws(function() { + var batch = {}; + batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { + code: 0, + details: 'details string', + metadata: 'abc' + }; + call.startBatch(batch, function(){}); + }, TypeError); + }); + }); describe('cancel', function() { it('should succeed', function() { var call = new grpc.Call(channel, 'method', getDeadline(1)); From a3d649c33b565c95fb32e27880903a9a6570a065 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 1 Aug 2017 10:41:52 -0700 Subject: [PATCH 2/2] Split tests more granularly --- test/call_test.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/test/call_test.js b/test/call_test.js index e19f47be..b5246c4f 100644 --- a/test/call_test.js +++ b/test/call_test.js @@ -189,18 +189,24 @@ describe('call', function() { }); }); describe('startBatch with message', function() { - it('should fail with non-buffer arguments', function() { + it('should fail with null argument', function() { var call = new grpc.Call(channel, 'method', getDeadline(1)); assert.throws(function() { var batch = {}; batch[grpc.opType.SEND_MESSAGE] = null; call.startBatch(batch, function(){}); }, TypeError); + }); + it('should fail with numeric argument', function() { + var call = new grpc.Call(channel, 'method', getDeadline(1)); assert.throws(function() { var batch = {}; batch[grpc.opType.SEND_MESSAGE] = 5; call.startBatch(batch, function(){}); }, TypeError); + }); + it('should fail with string argument', function() { + var call = new grpc.Call(channel, 'method', getDeadline(1)); assert.throws(function() { var batch = {}; batch[grpc.opType.SEND_MESSAGE] = 'value'; @@ -242,7 +248,7 @@ describe('call', function() { call.startBatch(batch, function(){}); }, TypeError); }); - it('should fail with incorrectly typed arguments', function() { + it('should fail with incorrectly typed code argument', function() { var call = new grpc.Call(channel, 'method', getDeadline(1)); assert.throws(function() { var batch = {}; @@ -253,6 +259,9 @@ describe('call', function() { }; call.startBatch(batch, function(){}); }, TypeError); + }); + it('should fail with incorrectly typed details argument', function() { + var call = new grpc.Call(channel, 'method', getDeadline(1)); assert.throws(function() { var batch = {}; batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { @@ -262,6 +271,9 @@ describe('call', function() { }; call.startBatch(batch, function(){}); }, TypeError); + }); + it('should fail with incorrectly typed metadata argument', function() { + var call = new grpc.Call(channel, 'method', getDeadline(1)); assert.throws(function() { var batch = {}; batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {