0001-PHP-7.3-compatibility-and-bugfixes.patch 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. From 6ea688eff5157785267d2b671cf62d296288847f Mon Sep 17 00:00:00 2001
  2. From: Alex/AT <alex@alex-at.net>
  3. Date: Mon, 10 Dec 2018 06:02:27 +0300
  4. Subject: [PATCH] PHP 7.3 compatibility and bugfixes
  5. - Define new GC_ADDREF/DELREF/SET_REFCOUNT macros for older PHP versions and use them instead of direct GC reference counter access
  6. - Fixup all necessary 'long' type parameters to 'zend_long', PHP 7.3 makes it mandatory, also fixup some direct function implementations to accept the same
  7. - In php_zmq_recv(), zend_string_init() was wrongly called with third parameter as '1', marking new string with IS_STR_PERSISTENT, this caused heap corruption and/or segfaults with PHP 7.3 and could possibly cause other sorts of bugs under any 7.x version
  8. With ZVAL_STRINGL macro, this last '1' parameter meant to copy the string and was seemingly erroneously moved to zend_string_init(). zend_string_init() copies string by default, and last parameter has totally different meaning here
  9. - In poll(), flag ZVAL separation on passed arrays (PHP 7.3 makes it mandatory)
  10. - Test 19 (exception on connect callback with forced reference parameter): skip on PHP 7.1 and higher, PHP >= 7.1 started to fallback to passing argument by value instead of failing
  11. - Test 21 (warning generation from callback): it is ok, but PHP 7.3 uses 'int' instead of 'integer' for constants, so allow any word in place of the word 'integer'
  12. [Frank: backport from upstream PR https://github.com/mkoppanen/php-zmq/pull/195]
  13. Signed-off-by: Frank Hunleth <fhunleth@troodon-software.com>
  14. ---
  15. php_zmq.h | 6 ++++
  16. tests/019-callbackinvalidsignature.phpt | 3 +-
  17. tests/021-callbackwarning.phpt | 2 +-
  18. zmq.c | 40 ++++++++++++-------------
  19. zmq_sockopt.c | 4 +--
  20. 5 files changed, 30 insertions(+), 25 deletions(-)
  21. diff --git a/php_zmq.h b/php_zmq.h
  22. index ef50bfb..3833967 100644
  23. --- a/php_zmq.h
  24. +++ b/php_zmq.h
  25. @@ -44,6 +44,12 @@
  26. #include "php.h"
  27. +#if PHP_VERSION_ID < 70300
  28. +#define GC_ADDREF(p) ++GC_REFCOUNT(p)
  29. +#define GC_DELREF(p) --GC_REFCOUNT(p)
  30. +#define GC_SET_REFCOUNT(p, rc) GC_REFCOUNT(p) = rc
  31. +#endif
  32. +
  33. extern zend_module_entry zmq_module_entry;
  34. #define phpext_zmq_ptr &zmq_module_entry
  35. diff --git a/tests/019-callbackinvalidsignature.phpt b/tests/019-callbackinvalidsignature.phpt
  36. index 753de31..b5bb20c 100644
  37. --- a/tests/019-callbackinvalidsignature.phpt
  38. +++ b/tests/019-callbackinvalidsignature.phpt
  39. @@ -1,7 +1,8 @@
  40. --TEST--
  41. Test callback edge-cases
  42. --SKIPIF--
  43. -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
  44. +<?php require_once(dirname(__FILE__) . '/skipif.inc');
  45. +if (PHP_VERSION_ID >= 70100) die("skip PHP 7.1 and higher fallback to passing argument by value even when forced to reference"); ?>
  46. --FILE--
  47. <?php
  48. diff --git a/tests/021-callbackwarning.phpt b/tests/021-callbackwarning.phpt
  49. index 435743e..eba2ecf 100644
  50. --- a/tests/021-callbackwarning.phpt
  51. +++ b/tests/021-callbackwarning.phpt
  52. @@ -13,5 +13,5 @@ function generate_warning($a, $b)
  53. $socket = new ZMQSocket(new ZMQContext(), ZMQ::SOCKET_REQ, 'persistent_socket', 'generate_warning');
  54. --EXPECTF--
  55. -Warning: in_array() expects parameter 2 to be array, integer given in %s on line %d
  56. +Warning: in_array() expects parameter 2 to be array, %s given in %s on line %d
  57. diff --git a/zmq.c b/zmq.c
  58. index 942e69b..57ebd11 100644
  59. --- a/zmq.c
  60. +++ b/zmq.c
  61. @@ -235,7 +235,7 @@ php_zmq_context *php_zmq_context_get(zend_long io_threads, zend_bool is_persiste
  62. le.type = php_zmq_context_list_entry();
  63. le.ptr = context;
  64. - GC_REFCOUNT(&le) = 1;
  65. + GC_SET_REFCOUNT(&le, 1);
  66. /* plist_key is not a persistent allocated key, thus we use str_update here */
  67. if (zend_hash_str_update_mem(&EG(persistent_list), plist_key->val, plist_key->len, &le, sizeof(le)) == NULL) {
  68. @@ -369,7 +369,7 @@ PHP_METHOD(zmq, curvekeypair)
  69. PHP_METHOD(zmqcontext, __construct)
  70. {
  71. php_zmq_context_object *intern;
  72. - long io_threads = 1;
  73. + zend_long io_threads = 1;
  74. zend_bool is_persistent = 1;
  75. if (zend_parse_parameters(ZEND_NUM_ARGS(), "|lb", &io_threads, &is_persistent) == FAILURE) {
  76. @@ -495,7 +495,7 @@ PHP_METHOD(zmqcontext, getOpt)
  77. Create a new zmq socket
  78. */
  79. static
  80. -php_zmq_socket *php_zmq_socket_new(php_zmq_context *context, int type, zend_bool is_persistent)
  81. +php_zmq_socket *php_zmq_socket_new(php_zmq_context *context, zend_long type, zend_bool is_persistent)
  82. {
  83. php_zmq_socket *zmq_sock;
  84. @@ -503,7 +503,7 @@ php_zmq_socket *php_zmq_socket_new(php_zmq_context *context, int type, zend_bool
  85. zmq_sock->z_socket = zmq_socket(context->z_ctx, type);
  86. zmq_sock->pid = getpid();
  87. zmq_sock->ctx = context;
  88. - zmq_sock->socket_type = type;
  89. + zmq_sock->socket_type = type;
  90. if (!zmq_sock->z_socket) {
  91. pefree(zmq_sock, is_persistent);
  92. @@ -535,7 +535,7 @@ void php_zmq_socket_store(php_zmq_socket *zmq_sock_p, zend_long type, zend_strin
  93. le.type = php_zmq_socket_list_entry();
  94. le.ptr = zmq_sock_p;
  95. - GC_REFCOUNT(&le) = 1;
  96. + GC_SET_REFCOUNT(&le, 1);
  97. plist_key = php_zmq_socket_plist_key(type, persistent_id, use_shared_ctx);
  98. @@ -796,7 +796,7 @@ PHP_METHOD(zmqsocket, __construct)
  99. /* {{{ static zend_bool php_zmq_send(php_zmq_socket_object *intern, char *message_param, long flags)
  100. */
  101. -static zend_bool php_zmq_send(php_zmq_socket_object *intern, zend_string *message_param, long flags)
  102. +static zend_bool php_zmq_send(php_zmq_socket_object *intern, zend_string *message_param, zend_long flags)
  103. {
  104. int rc, errno_;
  105. zmq_msg_t message;
  106. @@ -828,7 +828,7 @@ static void php_zmq_sendmsg_impl(INTERNAL_FUNCTION_PARAMETERS)
  107. {
  108. php_zmq_socket_object *intern;
  109. zend_string *message_param;
  110. - long flags = 0;
  111. + zend_long flags = 0;
  112. zend_bool ret;
  113. if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|l", &message_param, &flags) == FAILURE) {
  114. @@ -890,7 +890,7 @@ PHP_METHOD(zmqsocket, sendmulti)
  115. zval *messages;
  116. php_zmq_socket_object *intern;
  117. int to_send, ret = 0;
  118. - long flags = 0;
  119. + zend_long flags = 0;
  120. if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|l", &messages, &flags) == FAILURE) {
  121. return;
  122. @@ -910,7 +910,7 @@ PHP_METHOD(zmqsocket, sendmulti)
  123. /* {{{ static zend_bool php_zmq_recv(php_zmq_socket_object *intern, long flags, zval *return_value)
  124. */
  125. static
  126. -zend_string *php_zmq_recv(php_zmq_socket_object *intern, long flags)
  127. +zend_string *php_zmq_recv(php_zmq_socket_object *intern, zend_long flags)
  128. {
  129. int rc, errno_;
  130. zmq_msg_t message;
  131. @@ -933,7 +933,7 @@ zend_string *php_zmq_recv(php_zmq_socket_object *intern, long flags)
  132. return NULL;
  133. }
  134. - str = zend_string_init(zmq_msg_data(&message), zmq_msg_size(&message), 1);
  135. + str = zend_string_init(zmq_msg_data(&message), zmq_msg_size(&message), 0);
  136. zmq_msg_close(&message);
  137. return str;
  138. }
  139. @@ -943,7 +943,7 @@ static void php_zmq_recvmsg_impl(INTERNAL_FUNCTION_PARAMETERS)
  140. {
  141. zend_string *str = NULL;
  142. php_zmq_socket_object *intern;
  143. - long flags = 0;
  144. + zend_long flags = 0;
  145. if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &flags) == FAILURE) {
  146. return;
  147. @@ -974,7 +974,7 @@ PHP_METHOD(zmqsocket, recvmulti)
  148. {
  149. php_zmq_socket_object *intern;
  150. size_t value_len;
  151. - long flags = 0;
  152. + zend_long flags = 0;
  153. #if ZMQ_VERSION_MAJOR < 3
  154. int64_t value;
  155. #else
  156. @@ -1303,7 +1303,7 @@ PHP_METHOD(zmqpoll, add)
  157. {
  158. php_zmq_poll_object *intern;
  159. zval *object;
  160. - long events;
  161. + zend_long events;
  162. int error;
  163. zend_string *key;
  164. @@ -1423,10 +1423,10 @@ PHP_METHOD(zmqpoll, poll)
  165. php_zmq_poll_object *intern;
  166. zval *r_array, *w_array;
  167. - long timeout = -1;
  168. + zend_long timeout = -1;
  169. int rc;
  170. - if (zend_parse_parameters(ZEND_NUM_ARGS(), "a!a!|l", &r_array, &w_array, &timeout) == FAILURE) {
  171. + if (zend_parse_parameters(ZEND_NUM_ARGS(), "a!/a!/|l", &r_array, &w_array, &timeout) == FAILURE) {
  172. return;
  173. }
  174. @@ -1592,7 +1592,7 @@ void s_clear_device_callback (php_zmq_device_cb_t *cb)
  175. }
  176. static
  177. -void s_init_device_callback (php_zmq_device_cb_t *cb, zend_fcall_info *fci, zend_fcall_info_cache *fci_cache, long timeout, zval *user_data)
  178. +void s_init_device_callback (php_zmq_device_cb_t *cb, zend_fcall_info *fci, zend_fcall_info_cache *fci_cache, zend_long timeout, zval *user_data)
  179. {
  180. memcpy (&cb->fci, fci, sizeof (zend_fcall_info));
  181. memcpy (&cb->fci_cache, fci_cache, sizeof (zend_fcall_info_cache));
  182. @@ -1615,7 +1615,7 @@ void s_init_device_callback (php_zmq_device_cb_t *cb, zend_fcall_info *fci, zend
  183. PHP_METHOD(zmqdevice, setidletimeout)
  184. {
  185. php_zmq_device_object *intern;
  186. - long timeout;
  187. + zend_long timeout;
  188. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &timeout) == FAILURE) {
  189. return;
  190. @@ -1644,7 +1644,7 @@ PHP_METHOD(zmqdevice, getidletimeout)
  191. PHP_METHOD(zmqdevice, settimertimeout)
  192. {
  193. php_zmq_device_object *intern;
  194. - long timeout;
  195. + zend_long timeout;
  196. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &timeout) == FAILURE) {
  197. return;
  198. @@ -1676,7 +1676,7 @@ PHP_METHOD(zmqdevice, setidlecallback)
  199. zval *user_data = NULL;
  200. zend_fcall_info fci;
  201. zend_fcall_info_cache fci_cache;
  202. - long timeout = 0;
  203. + zend_long timeout = 0;
  204. if (ZEND_NUM_ARGS() == 2) {
  205. php_error_docref(NULL, E_DEPRECATED, "The signature for setIdleCallback has changed, please update your code");
  206. @@ -1718,7 +1718,7 @@ PHP_METHOD(zmqdevice, settimercallback)
  207. zval *user_data = NULL;
  208. zend_fcall_info fci;
  209. zend_fcall_info_cache fci_cache;
  210. - long timeout;
  211. + zend_long timeout;
  212. if (zend_parse_parameters(ZEND_NUM_ARGS(), "fl|z!", &fci, &fci_cache, &timeout, &user_data) == FAILURE) {
  213. return;
  214. diff --git a/zmq_sockopt.c b/zmq_sockopt.c
  215. index 1357032..3a00421 100644
  216. --- a/zmq_sockopt.c
  217. +++ b/zmq_sockopt.c
  218. @@ -1,5 +1,3 @@
  219. -
  220. -
  221. /*
  222. +-----------------------------------------------------------------------------------+
  223. | ZMQ extension for PHP |
  224. @@ -2033,7 +2031,7 @@ PHP_METHOD(zmqsocket, getsockopt)
  225. PHP_METHOD(zmqsocket, setsockopt)
  226. {
  227. php_zmq_socket_object *intern;
  228. - long key;
  229. + zend_long key;
  230. zval *zv;
  231. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz/", &key, &zv) == FAILURE) {
  232. --
  233. 2.17.1