diff --git a/helper.c b/helper.c index 84c898d2f1..76b3bcd85c 100644 --- a/helper.c +++ b/helper.c @@ -217,6 +217,35 @@ int php_git2_cb_init(php_git2_cb_t **out, zend_fcall_info *fci, zend_fcall_info_ cb->payload = payload; cb->fci = fci; cb->fcc = fcc; + cb->is_copy = 0; + GIT2_TSRMLS_SET2(cb, TSRMLS_C); + + *out = cb; + return 0; +} + +int php_git2_cb_init_copy(php_git2_cb_t **out, zend_fcall_info *fci, zend_fcall_info_cache *fcc, void *payload TSRMLS_DC) +{ + php_git2_cb_t *cb; + + cb = (struct php_git2_cb_t*)emalloc(sizeof(php_git2_cb_t)); + if (cb == NULL) { + return 1; + } + + cb->payload = payload; + // use fci->size instead of sizeof? + cb->fci = (zend_fcall_info*)emalloc(sizeof(zend_fcall_info)); + cb->fcc = (zend_fcall_info_cache*)emalloc(sizeof(zend_fcall_info_cache)); + memcpy(cb->fci, fci, sizeof(zend_fcall_info)); + memcpy(cb->fcc, fcc, sizeof(zend_fcall_info_cache)); + Z_ADDREF_P(cb->fci->function_name); +#if PHP_VERSION_ID >= 50300 + if (cb->fci->object_ptr) { + Z_ADDREF_P(cb->fci->object_ptr); + } +#endif + cb->is_copy = 1; GIT2_TSRMLS_SET2(cb, TSRMLS_C); *out = cb; @@ -225,6 +254,14 @@ int php_git2_cb_init(php_git2_cb_t **out, zend_fcall_info *fci, zend_fcall_info_ void php_git2_cb_free(php_git2_cb_t *target) { + if (target->is_copy) { + Z_DELREF_P(target->fci->function_name); +#if PHP_VERSION_ID >= 50300 + if (target->fci->object_ptr) { + Z_DELREF_P(target->fci->object_ptr); + } +#endif + } efree(target); } diff --git a/helper.h b/helper.h index 424f1c3f89..3cf5e942d5 100644 --- a/helper.h +++ b/helper.h @@ -49,6 +49,8 @@ int php_git2_call_function_v( int php_git2_cb_init(php_git2_cb_t **out, zend_fcall_info *fci, zend_fcall_info_cache *fcc, void *payload TSRMLS_DC); +int php_git2_cb_init_copy(php_git2_cb_t **out, zend_fcall_info *fci, zend_fcall_info_cache *fcc, void *payload TSRMLS_DC); + void php_git2_cb_free(php_git2_cb_t *target); void php_git2_array_to_strarray(git_strarray *out, zval *array TSRMLS_DC); @@ -100,4 +102,4 @@ void php_git2_fcall_info_wrapper(zval *target, zend_fcall_info **out_fci, zend_f void php_git2_fcall_info_wrapper2(zval *target, zend_fcall_info *fci, zend_fcall_info_cache *fcc TSRMLS_DC); -#endif \ No newline at end of file +#endif diff --git a/php_git2.h b/php_git2.h index 4c5493a976..43b9c2850b 100644 --- a/php_git2.h +++ b/php_git2.h @@ -203,6 +203,7 @@ typedef struct php_git2_cb_t { zval *payload; zend_fcall_info *fci; zend_fcall_info_cache *fcc; + int is_copy; GIT2_TSRMLS_DECL } php_git2_cb_t; diff --git a/transport.c b/transport.c index 4904517ab5..4860723f60 100644 --- a/transport.c +++ b/transport.c @@ -73,11 +73,10 @@ PHP_FUNCTION(git_transport_register) return; } - if (php_git2_cb_init(&cb, &fci, &fcc, param TSRMLS_CC)) { + if (php_git2_cb_init_copy(&cb, &fci, &fcc, param TSRMLS_CC)) { RETURN_FALSE; } result = git_transport_register(prefix, priority, php_git2_transport_cb, cb); - php_git2_cb_free(cb); RETURN_LONG(result); } /* }}} */