From 8d770144c259abbd7a307e96f9aec5e9bda1c4ea Mon Sep 17 00:00:00 2001
From: thinkerou <thinkerou@gmail.com>
Date: Tue, 10 Jan 2017 13:26:42 +0800
Subject: [PATCH] attempt to fix mem leaks

---
 src/php/ext/grpc/call.c                |  2 ++
 src/php/ext/grpc/call_credentials.c    | 10 +++---
 src/php/ext/grpc/channel_credentials.c | 12 ++------
 src/php/ext/grpc/php7_wrapper.h        | 12 ++++++++
 src/php/ext/grpc/php_grpc.h            |  4 ---
 src/php/ext/grpc/server_credentials.c  |  4 +--
 src/php/ext/grpc/timeval.c             | 42 +++++++++-----------------
 7 files changed, 36 insertions(+), 50 deletions(-)

diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index 3a49ea8708..64b1137c2a 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -478,6 +478,7 @@ PHP_METHOD(Call, startBatch) {
                                    true);
       add_property_zval(result, "status", recv_status);
       PHP_GRPC_DELREF(recv_status);
+      PHP_GRPC_FREE_STD_ZVAL(recv_status);
       break;
     case GRPC_OP_RECV_CLOSE_ON_SERVER:
       add_property_bool(result, "cancelled", cancelled);
@@ -501,6 +502,7 @@ cleanup:
     }
     if (ops[i].op == GRPC_OP_RECV_MESSAGE) {
       grpc_byte_buffer_destroy(message);
+      PHP_GRPC_FREE_STD_ZVAL(message_str);
     }
   }
   RETURN_DESTROY_ZVAL(result);
diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c
index 3aafc3a19b..043817facd 100644
--- a/src/php/ext/grpc/call_credentials.c
+++ b/src/php/ext/grpc/call_credentials.c
@@ -111,9 +111,7 @@ PHP_METHOD(CallCredentials, createComposite) {
   grpc_call_credentials *creds =
       grpc_composite_call_credentials_create(cred1->wrapped, cred2->wrapped,
                                              NULL);
-  zval *creds_object;
-  PHP_GRPC_MAKE_STD_ZVAL(creds_object);
-  creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC);
+  zval *creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC);
   RETURN_DESTROY_ZVAL(creds_object);
 }
 
@@ -155,9 +153,7 @@ PHP_METHOD(CallCredentials, createFromPlugin) {
 
   grpc_call_credentials *creds =
     grpc_metadata_credentials_create_from_plugin(plugin, NULL);
-  zval *creds_object;
-  PHP_GRPC_MAKE_STD_ZVAL(creds_object);
-  creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC);
+  zval *creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC);
   RETURN_DESTROY_ZVAL(creds_object);
 }
 
@@ -211,6 +207,8 @@ void plugin_destroy_state(void *ptr) {
   plugin_state *state = (plugin_state *)ptr;
   efree(state->fci);
   efree(state->fci_cache);
+  PHP_GRPC_FREE_STD_ZVAL(state->fci->params);
+  PHP_GRPC_FREE_STD_ZVAL(state->fci->retval);
   efree(state);
 }
 
diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c
index a32c4a4ea2..36a8223b88 100644
--- a/src/php/ext/grpc/channel_credentials.c
+++ b/src/php/ext/grpc/channel_credentials.c
@@ -121,9 +121,7 @@ PHP_METHOD(ChannelCredentials, setDefaultRootsPem) {
  */
 PHP_METHOD(ChannelCredentials, createDefault) {
   grpc_channel_credentials *creds = grpc_google_default_credentials_create();
-  zval *creds_object;
-  PHP_GRPC_MAKE_STD_ZVAL(creds_object);
-  creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
+  zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
   RETURN_DESTROY_ZVAL(creds_object);
 }
 
@@ -160,9 +158,7 @@ PHP_METHOD(ChannelCredentials, createSsl) {
   grpc_channel_credentials *creds = grpc_ssl_credentials_create(
       pem_root_certs,
       pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair, NULL);
-  zval *creds_object;
-  PHP_GRPC_MAKE_STD_ZVAL(creds_object);
-  creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
+  zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
   RETURN_DESTROY_ZVAL(creds_object);
 }
 
@@ -191,9 +187,7 @@ PHP_METHOD(ChannelCredentials, createComposite) {
   grpc_channel_credentials *creds =
       grpc_composite_channel_credentials_create(cred1->wrapped, cred2->wrapped,
                                                 NULL);
-  zval *creds_object;
-  PHP_GRPC_MAKE_STD_ZVAL(creds_object);
-  creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
+  zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC);
   RETURN_DESTROY_ZVAL(creds_object);
 }
 
diff --git a/src/php/ext/grpc/php7_wrapper.h b/src/php/ext/grpc/php7_wrapper.h
index 1d7824113f..72e982d6fc 100644
--- a/src/php/ext/grpc/php7_wrapper.h
+++ b/src/php/ext/grpc/php7_wrapper.h
@@ -50,8 +50,13 @@
 
 #define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val, dup)
 #define PHP_GRPC_MAKE_STD_ZVAL(pzv) MAKE_STD_ZVAL(pzv)
+#define PHP_GRPC_FREE_STD_ZVAL(pzv)
 #define PHP_GRPC_DELREF(zv) Z_DELREF_P(zv)
 
+#define RETURN_DESTROY_ZVAL(val) \
+  RETURN_ZVAL(val, false /* Don't execute copy constructor */, \
+              true /* Dealloc original before returning */)
+
 #define PHP_GRPC_WRAP_OBJECT_START(name) \
   typedef struct name { \
     zend_object std;
@@ -144,8 +149,15 @@ static inline int php_grpc_zend_hash_find(HashTable *ht, char *key, int len,
 #define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val)
 #define PHP_GRPC_MAKE_STD_ZVAL(pzv) \
   pzv = (zval *)emalloc(sizeof(zval));
+#define PHP_GRPC_FREE_STD_ZVAL(pzv) efree(pzv);
 #define PHP_GRPC_DELREF(zv)
 
+#define RETURN_DESTROY_ZVAL(val) \
+  RETVAL_ZVAL(val, false /* Don't execute copy constructor */, \
+              true /* Dealloc original before returning */); \
+  efree(val); \
+  return
+
 #define PHP_GRPC_WRAP_OBJECT_START(name) \
   typedef struct name {
 #define PHP_GRPC_WRAP_OBJECT_END(name) \
diff --git a/src/php/ext/grpc/php_grpc.h b/src/php/ext/grpc/php_grpc.h
index e57a06545e..13083b0bc7 100644
--- a/src/php/ext/grpc/php_grpc.h
+++ b/src/php/ext/grpc/php_grpc.h
@@ -61,10 +61,6 @@ extern zend_module_entry grpc_module_entry;
 
 #include "grpc/grpc.h"
 
-#define RETURN_DESTROY_ZVAL(val)                               \
-  RETURN_ZVAL(val, false /* Don't execute copy constructor */, \
-              true /* Dealloc original before returning */)
-
 /* These are all function declarations */
 /* Code that runs at module initialization */
 PHP_MINIT_FUNCTION(grpc);
diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c
index 1610c8ebb0..3e39fee246 100644
--- a/src/php/ext/grpc/server_credentials.c
+++ b/src/php/ext/grpc/server_credentials.c
@@ -113,9 +113,7 @@ PHP_METHOD(ServerCredentials, createSsl) {
   grpc_server_credentials *creds = grpc_ssl_server_credentials_create_ex(
       pem_root_certs, &pem_key_cert_pair, 1,
       GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, NULL);
-  zval *creds_object;
-  PHP_GRPC_MAKE_STD_ZVAL(creds_object);
-  creds_object = grpc_php_wrap_server_credentials(creds TSRMLS_CC);
+  zval *creds_object = grpc_php_wrap_server_credentials(creds TSRMLS_CC);
   RETURN_DESTROY_ZVAL(creds_object);
 }
 
diff --git a/src/php/ext/grpc/timeval.c b/src/php/ext/grpc/timeval.c
index 945231b47f..7ada915aad 100644
--- a/src/php/ext/grpc/timeval.c
+++ b/src/php/ext/grpc/timeval.c
@@ -115,11 +115,9 @@ PHP_METHOD(Timeval, add) {
   }
   wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis());
   wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj);
-  zval *sum;
-  PHP_GRPC_MAKE_STD_ZVAL(sum);
-  sum =
-      grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped)
-                            TSRMLS_CC);
+  zval *sum =
+    grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped)
+                          TSRMLS_CC);
   RETURN_DESTROY_ZVAL(sum);
 }
 
@@ -141,11 +139,9 @@ PHP_METHOD(Timeval, subtract) {
   }
   wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis());
   wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj);
-  zval *diff;
-  PHP_GRPC_MAKE_STD_ZVAL(diff);
-  diff =
-      grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped)
-                            TSRMLS_CC);
+  zval *diff =
+    grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped)
+                          TSRMLS_CC);
   RETURN_DESTROY_ZVAL(diff);
 }
 
@@ -206,9 +202,7 @@ PHP_METHOD(Timeval, similar) {
  * @return Timeval The current time
  */
 PHP_METHOD(Timeval, now) {
-  zval *now;
-  PHP_GRPC_MAKE_STD_ZVAL(now);
-  now = grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME) TSRMLS_CC);
+  zval *now = grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME) TSRMLS_CC);
   RETURN_DESTROY_ZVAL(now);
 }
 
@@ -217,13 +211,9 @@ PHP_METHOD(Timeval, now) {
  * @return Timeval Zero length time interval
  */
 PHP_METHOD(Timeval, zero) {
-  zval *grpc_php_timeval_zero;
-  PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_zero);
-  grpc_php_timeval_zero =
-      grpc_php_wrap_timeval(gpr_time_0(GPR_CLOCK_REALTIME) TSRMLS_CC);
-  RETURN_ZVAL(grpc_php_timeval_zero,
-              false, /* Copy original before returning? */
-              true /* Destroy original before returning */);
+  zval *grpc_php_timeval_zero =
+    grpc_php_wrap_timeval(gpr_time_0(GPR_CLOCK_REALTIME) TSRMLS_CC);
+  RETURN_DESTROY_ZVAL(grpc_php_timeval_zero);
 }
 
 /**
@@ -231,10 +221,8 @@ PHP_METHOD(Timeval, zero) {
  * @return Timeval Infinite future time value
  */
 PHP_METHOD(Timeval, infFuture) {
-  zval *grpc_php_timeval_inf_future;
-  PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_inf_future);
-  grpc_php_timeval_inf_future =
-      grpc_php_wrap_timeval(gpr_inf_future(GPR_CLOCK_REALTIME) TSRMLS_CC);
+  zval *grpc_php_timeval_inf_future =
+    grpc_php_wrap_timeval(gpr_inf_future(GPR_CLOCK_REALTIME) TSRMLS_CC);
   RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_future);
 }
 
@@ -243,10 +231,8 @@ PHP_METHOD(Timeval, infFuture) {
  * @return Timeval Infinite past time value
  */
 PHP_METHOD(Timeval, infPast) {
-  zval *grpc_php_timeval_inf_past;
-  PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_inf_past);
-  grpc_php_timeval_inf_past =
-      grpc_php_wrap_timeval(gpr_inf_past(GPR_CLOCK_REALTIME) TSRMLS_CC);
+  zval *grpc_php_timeval_inf_past =
+    grpc_php_wrap_timeval(gpr_inf_past(GPR_CLOCK_REALTIME) TSRMLS_CC);
   RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_past);
 }
 
-- 
GitLab