From 23d7e7f276852b4ed1bd2829fcca38c6db854563 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 7 Feb 2008 15:10:57 +0000 Subject: [PATCH] fix gc issues --- http_cookie_api.c | 16 +++++++++++----- http_headers_api.c | 7 +++++-- http_message_object.c | 24 +++++++++++++----------- http_querystring_api.c | 21 +++++++++++++-------- http_request_api.c | 41 ++++++++++++++++++++++++++++++++--------- http_url_api.c | 10 ++++++---- php_http_api.h | 42 +++++++++--------------------------------- php_http_request_int.h | 12 +++++++++--- 8 files changed, 98 insertions(+), 75 deletions(-) diff --git a/http_cookie_api.c b/http_cookie_api.c index f1710c3..2f0d6c5 100644 --- a/http_cookie_api.c +++ b/http_cookie_api.c @@ -249,9 +249,12 @@ PHP_HTTP_API http_cookie_list *_http_cookie_list_fromstruct(http_cookie_list *li list->flags = (long) Z_DVAL_PP(tmp); break; case IS_STRING: - cpy = zval_copy(IS_LONG, *tmp); - list->flags = Z_LVAL_P(cpy); - zval_free(&cpy); + cpy = *tmp; + convert_to_long_ex(&cpy); + list->flags = Z_LVAL_PP(tmp); + if (cpy != *tmp) { + zval_ptr_dtor(&cpy); + } break; default: break; @@ -266,7 +269,8 @@ PHP_HTTP_API http_cookie_list *_http_cookie_list_fromstruct(http_cookie_list *li list->expires = (long) Z_DVAL_PP(tmp); break; case IS_STRING: - cpy = zval_copy(IS_LONG, *tmp); + cpy = *tmp; + convert_to_long_ex(&cpy); if (Z_LVAL_P(cpy)) { list->expires = Z_LVAL_P(cpy); } else { @@ -275,7 +279,9 @@ PHP_HTTP_API http_cookie_list *_http_cookie_list_fromstruct(http_cookie_list *li list->expires = expires; } } - zval_free(&cpy); + if (cpy != *tmp) { + zval_ptr_dtor(&cpy); + } break; default: break; diff --git a/http_headers_api.c b/http_headers_api.c index dbbf999..1da83ae 100644 --- a/http_headers_api.c +++ b/http_headers_api.c @@ -501,9 +501,12 @@ PHP_HTTP_API zend_bool _http_match_request_header_ex(const char *header, const c http_get_request_headers(NULL); name = pretty_key(estrndup(header, name_len), name_len, 1, 1); if (SUCCESS == zend_hash_find(HTTP_G->request.headers, name, name_len+1, (void *) &data)) { - zvalue = zval_copy(IS_STRING, *data); + zvalue = *data; + convert_to_string_ex(&zvalue); result = (match_case ? strcmp(Z_STRVAL_P(zvalue), value) : strcasecmp(Z_STRVAL_P(zvalue), value)) ? 0 : 1; - zval_free(&zvalue); + if (zvalue != *data) { + zval_ptr_dtor(&zvalue); + } } efree(name); diff --git a/http_message_object.c b/http_message_object.c index 3853231..acb8a1d 100644 --- a/http_message_object.c +++ b/http_message_object.c @@ -525,7 +525,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va { getObjectEx(http_message_object, obj, object); http_message *msg = obj->message; - zval *cpy = NULL; + zval *cpy; #ifdef WONKY ulong h = zend_hash_func(Z_STRVAL_P(member), Z_STRLEN_P(member) + 1); #else @@ -537,7 +537,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va } #endif - cpy = zval_copy(Z_TYPE_P(value), value); + cpy = value; #ifdef WONKY switch (h) @@ -547,26 +547,26 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va { case HTTP_MSG_PROPHASH_TYPE: case HTTP_MSG_CHILD_PROPHASH_TYPE: - convert_to_long(cpy); + convert_to_long_ex(&cpy); http_message_set_type(msg, Z_LVAL_P(cpy)); break; case HTTP_MSG_PROPHASH_HTTP_VERSION: case HTTP_MSG_CHILD_PROPHASH_HTTP_VERSION: - convert_to_double(cpy); + convert_to_double_ex(&cpy); msg->http.version = Z_DVAL_P(cpy); break; case HTTP_MSG_PROPHASH_BODY: case HTTP_MSG_CHILD_PROPHASH_BODY: - convert_to_string(cpy); + convert_to_string_ex(&cpy); phpstr_dtor(PHPSTR(msg)); phpstr_from_string_ex(PHPSTR(msg), Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)); break; case HTTP_MSG_PROPHASH_HEADERS: case HTTP_MSG_CHILD_PROPHASH_HEADERS: - convert_to_array(cpy); + convert_to_array_ex(&cpy); zend_hash_clean(&msg->hdrs); zend_hash_copy(&msg->hdrs, Z_ARRVAL_P(cpy), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); break; @@ -587,7 +587,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va case HTTP_MSG_PROPHASH_REQUEST_METHOD: case HTTP_MSG_CHILD_PROPHASH_REQUEST_METHOD: if (HTTP_MSG_TYPE(REQUEST, msg)) { - convert_to_string(cpy); + convert_to_string_ex(&cpy); STR_SET(msg->http.info.request.method, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy))); } break; @@ -595,7 +595,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va case HTTP_MSG_PROPHASH_REQUEST_URL: case HTTP_MSG_CHILD_PROPHASH_REQUEST_URL: if (HTTP_MSG_TYPE(REQUEST, msg)) { - convert_to_string(cpy); + convert_to_string_ex(&cpy); STR_SET(msg->http.info.request.url, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy))); } break; @@ -603,7 +603,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va case HTTP_MSG_PROPHASH_RESPONSE_CODE: case HTTP_MSG_CHILD_PROPHASH_RESPONSE_CODE: if (HTTP_MSG_TYPE(RESPONSE, msg)) { - convert_to_long(cpy); + convert_to_long_ex(&cpy); msg->http.info.response.code = Z_LVAL_P(cpy); } break; @@ -611,7 +611,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va case HTTP_MSG_PROPHASH_RESPONSE_STATUS: case HTTP_MSG_CHILD_PROPHASH_RESPONSE_STATUS: if (HTTP_MSG_TYPE(RESPONSE, msg)) { - convert_to_string(cpy); + convert_to_string_ex(&cpy); STR_SET(msg->http.info.response.status, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy))); } break; @@ -622,7 +622,9 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va #endif break; } - zval_free(&cpy); + if (cpy != value) { + zval_ptr_dtor(&cpy); + } } static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC) diff --git a/http_querystring_api.c b/http_querystring_api.c index 899715d..5d636a3 100644 --- a/http_querystring_api.c +++ b/http_querystring_api.c @@ -116,14 +116,13 @@ PHP_HTTP_API int _http_querystring_modify(zval *qarray, zval *params TSRMLS_DC) return http_querystring_modify_array(qarray, params); } else if (Z_TYPE_P(params) == IS_OBJECT) { #ifdef ZEND_ENGINE_2 - if (!instanceof_function(Z_OBJCE_P(params), http_querystring_object_ce TSRMLS_CC)) { + if (instanceof_function(Z_OBJCE_P(params), http_querystring_object_ce TSRMLS_CC)) { + return http_querystring_modify_array(qarray, zend_read_property(THIS_CE, params, ZEND_STRS("queryArray")-1, 0 TSRMLS_CC)); + } else { #endif - zval temp_array; - INIT_ZARR(temp_array, HASH_OF(params)); - return http_querystring_modify_array(qarray, &temp_array); + return http_querystring_modify_array(qarray, params); #ifdef ZEND_ENGINE_2 } - return http_querystring_modify_array(qarray, zend_read_property(THIS_CE, params, ZEND_STRS("queryArray")-1, 0 TSRMLS_CC)); #endif } else { int rv; @@ -149,7 +148,7 @@ static inline int _http_querystring_modify_array(zval *qarray, zval *params TSRM HashPosition pos; zval **params_entry = NULL; - FOREACH_KEYVAL(pos, params, key, params_entry) { + FOREACH_HASH_KEYVAL(pos, HASH_OF(params), key, params_entry) { /* only public properties */ if ((key.type != HASH_KEY_IS_STRING || *key.str) && http_querystring_modify_array_ex(qarray, key.type, key.str, key.len, key.num, *params_entry)) { rv = 1; @@ -188,9 +187,15 @@ static inline int _http_querystring_modify_array_ex(zval *qarray, int key_type, } /* add */ - ZVAL_ADDREF(params_entry); if (Z_TYPE_P(params_entry) == IS_OBJECT) { - convert_to_array_ex(¶ms_entry); + zval *new_array; + + MAKE_STD_ZVAL(new_array); + array_init(new_array); + http_querystring_modify_array(new_array, params_entry); + params_entry = new_array; + } else { + ZVAL_ADDREF(params_entry); } if (key_type == HASH_KEY_IS_STRING) { add_assoc_zval_ex(qarray, key, keylen, params_entry); diff --git a/http_request_api.c b/http_request_api.c index 728fe3f..e20eb11 100644 --- a/http_request_api.c +++ b/http_request_api.c @@ -637,14 +637,20 @@ PHP_HTTP_API STATUS _http_request_prepare(http_request *request, HashTable *opti if (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(zoption), (void *) &prs)) { zend_hash_move_forward(Z_ARRVAL_P(zoption)); if (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(zoption), (void *) &pre)) { - zval *prs_cpy = zval_copy(IS_LONG, *prs), *pre_cpy = zval_copy(IS_LONG, *pre); + zval *prs_cpy = *prs, *pre_cpy = *pre; + convert_to_long_ex(&prs_cpy); + convert_to_long_ex(&pre_cpy); if (Z_LVAL_P(prs_cpy) && Z_LVAL_P(pre_cpy)) { HTTP_CURL_OPT(CURLOPT_LOCALPORT, MIN(Z_LVAL_P(prs_cpy), Z_LVAL_P(pre_cpy))); HTTP_CURL_OPT(CURLOPT_LOCALPORTRANGE, labs(Z_LVAL_P(prs_cpy)-Z_LVAL_P(pre_cpy))+1L); } - zval_free(&prs_cpy); - zval_free(&pre_cpy); + if (prs_cpy != *prs) { + zval_ptr_dtor(&prs_cpy); + } + if (pre_cpy != *pre) { + zval_ptr_dtor(&pre_cpy); + } } } } @@ -720,13 +726,19 @@ PHP_HTTP_API STATUS _http_request_prepare(http_request *request, HashTable *opti if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(rr), (void *) &re, &pos2)) { if ( ((Z_TYPE_PP(rb) == IS_LONG) || ((Z_TYPE_PP(rb) == IS_STRING) && is_numeric_string(Z_STRVAL_PP(rb), Z_STRLEN_PP(rb), NULL, NULL, 1))) && ((Z_TYPE_PP(re) == IS_LONG) || ((Z_TYPE_PP(re) == IS_STRING) && is_numeric_string(Z_STRVAL_PP(re), Z_STRLEN_PP(re), NULL, NULL, 1)))) { - zval *rbl = zval_copy(IS_LONG, *rb), *rel = zval_copy(IS_LONG, *re); + zval *rbl = *rb, *rel = *re; + convert_to_long_ex(&rbl); + convert_to_long_ex(&rel); if ((Z_LVAL_P(rbl) >= 0) && (Z_LVAL_P(rel) >= 0)) { phpstr_appendf(&rs, "%ld-%ld,", Z_LVAL_P(rbl), Z_LVAL_P(rel)); } - zval_free(&rbl); - zval_free(&rel); + if (rbl != *rb) { + zval_ptr_dtor(&rbl); + } + if (rel != *re) { + zval_ptr_dtor(&rel); + } } } } @@ -820,9 +832,12 @@ PHP_HTTP_API STATUS _http_request_prepare(http_request *request, HashTable *opti FOREACH_KEYVAL(pos, zoption, cookie_key, cookie_val) { if (cookie_key.type == HASH_KEY_IS_STRING) { - zval *val = zval_copy(IS_STRING, *cookie_val); + zval *val = *cookie_val; + convert_to_string_ex(&val); phpstr_appendf(&request->_cache.cookies, "%s=%s; ", cookie_key.str, Z_STRVAL_P(val)); - zval_free(&val); + if (val != *cookie_val) { + zval_ptr_dtor(&val); + } } } @@ -1159,7 +1174,15 @@ static inline zval *_http_request_option_ex(http_request *r, HashTable *options, ulong h = zend_hash_func(key, keylen); if (SUCCESS == zend_hash_quick_find(options, key, keylen, h, (void *) &zoption)) { - return http_request_option_cache_ex(r, key, keylen, h, zval_copy(type, *zoption)); + zval *copy; + + MAKE_STD_ZVAL(copy); + ZVAL_ZVAL(copy, *zoption, 1, 0); + + convert_to_type(type, copy); + http_request_option_cache_ex(r, key, keylen, h, copy); + zval_ptr_dtor(©); + return copy; } } diff --git a/http_url_api.c b/http_url_api.c index f67d91a..c0fad60 100644 --- a/http_url_api.c +++ b/http_url_api.c @@ -445,7 +445,9 @@ PHP_HTTP_API STATUS _http_urlencode_hash_recursive(HashTable *ht, phpstr *str, c return FAILURE; } } else { - zval *val = zval_copy(IS_STRING, *data); + zval val; + ZVAL_ZVAL(&val, *data, 1, 0); + convert_to_string(&val); if (PHPSTR_LEN(str)) { phpstr_append(str, arg_sep, arg_sep_len); @@ -453,16 +455,16 @@ PHP_HTTP_API STATUS _http_urlencode_hash_recursive(HashTable *ht, phpstr *str, c phpstr_append(str, PHPSTR_VAL(&new_prefix), PHPSTR_LEN(&new_prefix)); phpstr_appends(str, "="); - if (Z_STRLEN_P(val) && Z_STRVAL_P(val)) { + if (Z_STRLEN(val) && Z_STRVAL(val)) { char *encoded_val; int encoded_len; - encoded_val = php_url_encode(Z_STRVAL_P(val), Z_STRLEN_P(val), &encoded_len); + encoded_val = php_url_encode(Z_STRVAL(val), Z_STRLEN(val), &encoded_len); phpstr_append(str, encoded_val, encoded_len); efree(encoded_val); } - zval_free(&val); + zval_dtor(&val); } phpstr_dtor(&new_prefix); } diff --git a/php_http_api.h b/php_http_api.h index 809f142..a490347 100644 --- a/php_http_api.h +++ b/php_http_api.h @@ -267,7 +267,9 @@ static inline zval *_convert_to_type(int type, zval *z) #define convert_to_type_ex(t, z, p) _convert_to_type_ex((t), (z), (p)) static inline zval *_convert_to_type_ex(int type, zval *z, zval **p) { - *p = z; + if (p) { + *p = z; + } if (Z_TYPE_P(z) != type) { switch (type) { case IS_NULL: convert_to_null_ex(&z); break; @@ -279,42 +281,16 @@ static inline zval *_convert_to_type_ex(int type, zval *z, zval **p) case IS_OBJECT: convert_to_object_ex(&z); break; } } - if (*p == z) { - *p = NULL; - } else { - *p = z; + if (p) { + if (*p == z) { + *p = NULL; + } else { + *p = z; + } } return z; } -#define zval_copy(t, z) _zval_copy((t), (z) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC) -static inline zval *_zval_copy(int type, zval *z ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) -{ - zval *copy; - - copy = emalloc_rel(sizeof(zval)); - *copy = *z; - zval_copy_ctor(copy); - convert_to_type(type, copy); -#ifdef Z_SET_REFCOUNT - Z_SET_REFCOUNT_P(copy, 0); - Z_UNSET_ISREF_P(copy); -#else - copy->refcount = 0; - copy->is_ref = 0; -#endif - - return copy; -} - -#define zval_free(z) _zval_free(z) -static inline void _zval_free(zval **z) -{ - zval_dtor(*z); - FREE_ZVAL(*z); - *z = NULL; -} - typedef struct _HashKey { char *str; uint len; diff --git a/php_http_request_int.h b/php_http_request_int.h index 5037bff..ed46b23 100644 --- a/php_http_request_int.h +++ b/php_http_request_int.h @@ -41,11 +41,14 @@ } #define HTTP_CURL_OPT_STRING_EX(keyname, optname, obdc) \ if (!strcasecmp(key.str, keyname)) { \ - zval *copy = http_request_option_cache_ex(request, keyname, strlen(keyname)+1, 0, zval_copy(IS_STRING, *param)); \ + zval *copy_tmp, *copy = http_request_option_cache_ex(request, keyname, strlen(keyname)+1, 0, convert_to_type_ex(IS_STRING, *param, ©_tmp)); \ if (obdc) { \ HTTP_CHECK_OPEN_BASEDIR(Z_STRVAL_P(copy), return FAILURE); \ } \ HTTP_CURL_OPT(optname, Z_STRVAL_P(copy)); \ + if (copy_tmp) { \ + zval_ptr_dtor(©_tmp); \ + } \ continue; \ } #define HTTP_CURL_OPT_LONG(OPTION, ldiff) \ @@ -55,9 +58,12 @@ } #define HTTP_CURL_OPT_LONG_EX(keyname, optname) \ if (!strcasecmp(key.str, keyname)) { \ - zval *copy = zval_copy(IS_LONG, *param); \ + zval *copy = *param; \ + convert_to_long_ex(©); \ HTTP_CURL_OPT(optname, Z_LVAL_P(copy)); \ - zval_free(©); \ + if (copy != *param) { \ + zval_ptr_dtor(©); \ + } \ continue; \ } -- 2.30.2