From 6f34bad568e6db5f78a908fa63bd08a1304366fa Mon Sep 17 00:00:00 2001
From: murgatroid99 <mlumish@google.com>
Date: Wed, 29 Jul 2015 10:09:36 -0700
Subject: [PATCH] Ensure that client generated methods don't conflict with
 other properties

---
 src/node/src/client.js        | 27 +++++++++++++++------------
 src/node/test/surface_test.js | 20 +++++++++++++++++++-
 2 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/src/node/src/client.js b/src/node/src/client.js
index f843669bd0..405e2be693 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -236,7 +236,7 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
       deadline = Infinity;
     }
     var emitter = new EventEmitter();
-    var call = new grpc.Call(this.channel, method, deadline);
+    var call = new grpc.Call(this.$channel, method, deadline);
     if (metadata === null || metadata === undefined) {
       metadata = {};
     }
@@ -246,7 +246,7 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
     emitter.getPeer = function getPeer() {
       return call.getPeer();
     };
-    this.updateMetadata(this.auth_uri, metadata, function(error, metadata) {
+    this.$updateMetadata(this.$auth_uri, metadata, function(error, metadata) {
       if (error) {
         call.cancel();
         callback(error);
@@ -309,12 +309,12 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) {
     if (deadline === undefined) {
       deadline = Infinity;
     }
-    var call = new grpc.Call(this.channel, method, deadline);
+    var call = new grpc.Call(this.$channel, method, deadline);
     if (metadata === null || metadata === undefined) {
       metadata = {};
     }
     var stream = new ClientWritableStream(call, serialize);
-    this.updateMetadata(this.auth_uri, metadata, function(error, metadata) {
+    this.$updateMetadata(this.$auth_uri, metadata, function(error, metadata) {
       if (error) {
         call.cancel();
         callback(error);
@@ -383,12 +383,12 @@ function makeServerStreamRequestFunction(method, serialize, deserialize) {
     if (deadline === undefined) {
       deadline = Infinity;
     }
-    var call = new grpc.Call(this.channel, method, deadline);
+    var call = new grpc.Call(this.$channel, method, deadline);
     if (metadata === null || metadata === undefined) {
       metadata = {};
     }
     var stream = new ClientReadableStream(call, deserialize);
-    this.updateMetadata(this.auth_uri, metadata, function(error, metadata) {
+    this.$updateMetadata(this.$auth_uri, metadata, function(error, metadata) {
       if (error) {
         call.cancel();
         stream.emit('error', error);
@@ -455,12 +455,12 @@ function makeBidiStreamRequestFunction(method, serialize, deserialize) {
     if (deadline === undefined) {
       deadline = Infinity;
     }
-    var call = new grpc.Call(this.channel, method, deadline);
+    var call = new grpc.Call(this.$channel, method, deadline);
     if (metadata === null || metadata === undefined) {
       metadata = {};
     }
     var stream = new ClientDuplexStream(call, serialize, deserialize);
-    this.updateMetadata(this.auth_uri, metadata, function(error, metadata) {
+    this.$updateMetadata(this.$auth_uri, metadata, function(error, metadata) {
       if (error) {
         call.cancel();
         stream.emit('error', error);
@@ -545,14 +545,17 @@ exports.makeClientConstructor = function(methods, serviceName) {
       options = {};
     }
     options['grpc.primary_user_agent'] = 'grpc-node/' + version;
-    this.channel = new grpc.Channel(address, options);
-    this.server_address = address.replace(/\/$/, '');
-    this.auth_uri = this.server_address + '/' + serviceName;
-    this.updateMetadata = updateMetadata;
+    this.$channel = new grpc.Channel(address, options);
+    this.$server_address = address.replace(/\/$/, '');
+    this.$auth_uri = this.$server_address + '/' + serviceName;
+    this.$updateMetadata = updateMetadata;
   }
 
   _.each(methods, function(attrs, name) {
     var method_type;
+    if (_.startsWith(name, '$')) {
+      throw new Error('Method names cannot start with $');
+    }
     if (attrs.requestStream) {
       if (attrs.responseStream) {
         method_type = 'bidi';
diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js
index 98f9b15bfc..1afdb33089 100644
--- a/src/node/test/surface_test.js
+++ b/src/node/test/surface_test.js
@@ -110,6 +110,24 @@ describe('Server.prototype.addProtoService', function() {
     });
   });
 });
+describe('Client constructor building', function() {
+  var illegal_service_attrs = {
+    $method : {
+      path: '/illegal/$method',
+      requestStream: false,
+      responseStream: false,
+      requestSerialize: _.identity,
+      requestDeserialize: _.identity,
+      responseSerialize: _.identity,
+      responseDeserialize: _.identity
+    }
+  };
+  it('Should reject method names starting with $', function() {
+    assert.throws(function() {
+      grpc.makeGenericClientConstructor(illegal_service_attrs);
+    }, /\$/);
+  });
+});
 describe('Echo service', function() {
   var server;
   var client;
@@ -344,7 +362,7 @@ describe('Other conditions', function() {
     server.shutdown();
   });
   it('channel.getTarget should be available', function() {
-    assert.strictEqual(typeof client.channel.getTarget(), 'string');
+    assert.strictEqual(typeof client.$channel.getTarget(), 'string');
   });
   describe('Server recieving bad input', function() {
     var misbehavingClient;
-- 
GitLab