fix gc issues
authorMichael Wallner <mike@php.net>
Thu, 7 Feb 2008 15:10:57 +0000 (15:10 +0000)
committerMichael Wallner <mike@php.net>
Thu, 7 Feb 2008 15:10:57 +0000 (15:10 +0000)
http_cookie_api.c
http_headers_api.c
http_message_object.c
http_querystring_api.c
http_request_api.c
http_url_api.c
php_http_api.h
php_http_request_int.h

index f1710c3..2f0d6c5 100644 (file)
@@ -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;
index dbbf999..1da83ae 100644 (file)
@@ -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);
 
index 3853231..acb8a1d 100644 (file)
@@ -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)
index 899715d..5d636a3 100644 (file)
@@ -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(&params_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);
index 728fe3f..e20eb11 100644 (file)
@@ -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(&copy);
+                       return copy;
                }
        }
        
index f67d91a..c0fad60 100644 (file)
@@ -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);
        }
index 809f142..a490347 100644 (file)
@@ -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;
index 5037bff..ed46b23 100644 (file)
        }
 #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, &copy_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(&copy_tmp); \
+               } \
                continue; \
        }
 #define HTTP_CURL_OPT_LONG(OPTION, ldiff) \
        }
 #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(&copy); \
                HTTP_CURL_OPT(optname, Z_LVAL_P(copy)); \
-               zval_free(&copy); \
+               if (copy != *param) { \
+                       zval_ptr_dtor(&copy); \
+               } \
                continue; \
        }