szend.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #include <stdlib.h>
  2. #include <stdint.h>
  3. #include "sztypes.h"
  4. #ifdef HAVE_CONFIG_H
  5. #include "config.h"
  6. #endif
  7. #include "zend_API.h"
  8. #ifdef ZEND_ENGINE_3
  9. int gozend_call_user_function(zval *object, char *func_name, zval *retval_ptr, int argc, zval *params)
  10. {
  11. zval function_name;
  12. ZVAL_NULL(&function_name);
  13. ZVAL_STRING(&function_name, func_name);
  14. assert(retval_ptr != NULL);
  15. if (call_user_function(CG(function_table), object , &function_name,
  16. retval_ptr, argc, params TSRMLS_CC) == SUCCESS) {
  17. return 0;
  18. }
  19. return -1;
  20. }
  21. #else /* ZEND_ENGINE_2 */
  22. int gozend_call_user_function(zval **object, char *func_name, zval *retval_ptr, int argc, zval **params)
  23. {
  24. zval function_name;
  25. INIT_ZVAL(function_name);
  26. ZVAL_STRING(&function_name, func_name, 1);
  27. assert(retval_ptr != NULL);
  28. if (call_user_function(CG(function_table), object , &function_name,
  29. retval_ptr, argc, params TSRMLS_CC) == SUCCESS) {
  30. return 0;
  31. }
  32. return -1;
  33. }
  34. #endif
  35. #ifdef ZEND_ENGINE_3
  36. static int gozend_call_user_function_string_ex(char *func_name, char *str, char **retstr, zval *object)
  37. {
  38. zval args[9];
  39. ZVAL_NULL(&args[0]);
  40. ZVAL_STRING(&args[0], str);
  41. zval retval_ptr;
  42. ZVAL_NULL(&retval_ptr);
  43. int ret = gozend_call_user_function(object, func_name, &retval_ptr, 1, args);
  44. if (ret == 0) {
  45. char *cstr = NULL;
  46. int cslen = 0;
  47. if (Z_TYPE_P(&retval_ptr) == IS_STRING) {
  48. cslen = Z_STRLEN_P(&retval_ptr);
  49. cstr = estrndup(Z_STRVAL_P(&retval_ptr), cslen);
  50. *retstr = cstr;
  51. }
  52. }
  53. return ret;
  54. }
  55. #else /* ZEND_ENGINE_2 */
  56. static int gozend_call_user_function_string_ex(char *func_name, char *str, char **retstr, zval **object)
  57. {
  58. zval *args[9];
  59. MAKE_STD_ZVAL(args[0]);
  60. ZVAL_STRING(args[0], str, 1);
  61. zval retval_ptr;
  62. ZVAL_NULL(&retval_ptr)
  63. int ret = gozend_call_user_function(object, func_name, &retval_ptr, 1, args);
  64. if (ret == 0) {
  65. char *cstr = NULL;
  66. int cslen = 0;
  67. if (Z_TYPE_P(&retval_ptr) == IS_STRING) {
  68. cslen = Z_STRLEN_P(&retval_ptr);
  69. cstr = estrndup(Z_STRVAL_P(&retval_ptr), cslen);
  70. *retstr = cstr;
  71. }
  72. }
  73. return ret;
  74. }
  75. #endif
  76. char *gozend_call_user_function_string(char *func_name, char *str)
  77. {
  78. char *res = NULL;
  79. int ret = gozend_call_user_function_string_ex(func_name, str, &res, NULL);
  80. return res;
  81. }
  82. int gozend_iszts() {
  83. #ifdef ZTS
  84. return 1;
  85. #else
  86. return 0;
  87. #endif
  88. }
  89. int gozend_zend_version_no() {
  90. #ifdef ZEND_ENGINE_3
  91. return 3;
  92. #else
  93. return 2;
  94. #endif
  95. }
  96. char* gozend_zend_version() {
  97. return get_zend_version();
  98. }
  99. void gozend_efree(void *ptr) {
  100. efree(ptr);
  101. }
  102. char *gozend_estrdup(char *str) {
  103. return estrdup(str);
  104. }
  105. char *gozend_estrndup(char *str, unsigned int length) {
  106. return estrndup(str, length);
  107. }
  108. void *gozend_emalloc(size_t size) {
  109. return emalloc(size);
  110. }
  111. void *gozend_ecalloc(size_t nmemb, size_t size) {
  112. return ecalloc(nmemb, size);
  113. }
  114. void *gozend_erealloc(void *ptr, size_t size) {
  115. return erealloc(ptr, size);
  116. }
  117. char gozend_eval_string(char *code)
  118. {
  119. zval retval;
  120. #ifdef ZEND_ENGINE_3
  121. ZVAL_NULL(&retval);
  122. #else
  123. INIT_ZVAL(retval);
  124. #endif
  125. int ret = zend_eval_string(code, &retval, (char*)"" TSRMLS_CC);
  126. // zval_ptr_dtor(&retval);
  127. zval_dtor(&retval);
  128. return ret == FAILURE;
  129. }
  130. void call_user_function_callback(char *data)
  131. {
  132. uint32_t argc = 0;
  133. zval retval_ptr;
  134. char *func_name = "say_hello_123";
  135. zval function_name;
  136. #ifdef ZEND_ENGINE_3
  137. ZVAL_NULL(&retval_ptr);
  138. ZVAL_NULL(&function_name);
  139. ZVAL_STRING(&function_name, func_name);
  140. #else
  141. INIT_ZVAL(retval_ptr);
  142. INIT_ZVAL(function_name);
  143. ZVAL_STRING(&function_name, func_name, 1);
  144. #endif
  145. void *cobj = NULL; /* no object */
  146. if (call_user_function(CG(function_table), cobj , &function_name,
  147. &retval_ptr, argc, NULL TSRMLS_CC) == SUCCESS) {
  148. /* do something with retval_ptr here if you like */
  149. }
  150. /* don't forget to free the zvals */
  151. // zval_ptr_dtor(&retval_ptr);
  152. zval_dtor(&function_name);
  153. }
  154. // find function name in HashTable
  155. static int _gozend_function_exists_ht(char *fname, HashTable* ht) {
  156. #ifdef ZEND_ENGINE_3
  157. zend_string *name;
  158. zend_function *func;
  159. zend_string *lcname;
  160. name = zend_string_init(fname, strlen(fname), 0);
  161. if (ZSTR_VAL(name)[0] == '\\') {
  162. /* Ignore leading "\" */
  163. lcname = zend_string_alloc(ZSTR_LEN(name) - 1, 0);
  164. zend_str_tolower_copy(ZSTR_VAL(lcname), ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1);
  165. } else {
  166. lcname = zend_string_tolower(name);
  167. }
  168. func = zend_hash_find_ptr(ht, lcname);
  169. zend_string_release(lcname);
  170. zend_string_release(name);
  171. /*
  172. * A bit of a hack, but not a bad one: we see if the handler of the function
  173. * is actually one that displays "function is disabled" message.
  174. */
  175. if (func && (func->type != ZEND_INTERNAL_FUNCTION ||
  176. func->internal_function.handler != zif_display_disabled_function)) {
  177. return 1;
  178. } else {
  179. return 0;
  180. }
  181. #else
  182. char *name;
  183. int name_len;
  184. zend_function *func;
  185. int retval = 0;
  186. name = fname;
  187. name_len = strlen(fname);
  188. /* Ignore leading "\" */
  189. if (name[0] == '\\') {
  190. name = &name[1];
  191. name_len--;
  192. }
  193. retval = (zend_hash_find(ht, name, name_len+1, (void **)&func) == SUCCESS);
  194. /*
  195. * A bit of a hack, but not a bad one: we see if the handler of the function
  196. * is actually one that displays "function is disabled" message.
  197. */
  198. if (retval && func->type == ZEND_INTERNAL_FUNCTION &&
  199. func->internal_function.handler == zif_display_disabled_function) {
  200. retval = 0;
  201. }
  202. return retval;
  203. #endif
  204. return 0;
  205. }
  206. // seems only can be used when vm executing
  207. int gozend_function_exists(char *fname) {
  208. return _gozend_function_exists_ht(fname, EG(function_table));
  209. }
  210. int gozend_function_registered(char *fname) {
  211. // zif_function_exists(); // this call method not compatible on MacOS
  212. // zif_function_existsccc();
  213. return _gozend_function_exists_ht(fname, CG(function_table));
  214. }