Fixed bug #15800
authorMichael Wallner <mike@php.net>
Thu, 12 Feb 2009 13:11:05 +0000 (13:11 +0000)
committerMichael Wallner <mike@php.net>
Thu, 12 Feb 2009 13:11:05 +0000 (13:11 +0000)
22 files changed:
ThanksTo.txt
http.c
http_api.c
http_cookie_api.c
http_filter_api.c
http_functions.c
http_headers_api.c
http_message_object.c
http_querystring_api.c
http_querystring_object.c
http_request_api.c
http_request_body_api.c
http_request_object.c
http_response_object.c
http_send_api.c
http_url_api.c
package2.xml
php_http_api.h
php_http_request_int.h
php_http_url_api.h
tests/HttpResponse_004.phpt
tests/bug_15800.phpt [new file with mode: 0644]

index f5f1da7..e736e4c 100644 (file)
@@ -8,8 +8,10 @@ to implement, in alphabetical order:
 
        Ilia Alshanetsky (ilia at php dot net)
        Petr Czaderna (petr at hroch dot info)
+       David James (james82 at gmail dot com)
        Thomas Landro Johnsen (thomas dot l dot johnsen at gmail dot com)
        Clay Loveless (clay at killersoft dot com)
+       Felipe Pena (felipe at php dot net)
        David Sklar (sklar at sklar dot com)
        Travis Swicegood (travis at mashery dot com)
        Alexey Zakhlestin (indeyets at gmail dot com)
diff --git a/http.c b/http.c
index 74d92b2..b0b04d8 100644 (file)
--- a/http.c
+++ b/http.c
@@ -487,9 +487,11 @@ PHP_MINFO_FUNCTION(http)
                                        FOREACH_KEYVAL(pos2, *val, ident, sub) {
                                                if (    SUCCESS == zend_hash_find(Z_ARRVAL_PP(sub), ZEND_STRS("used"), (void *) &zused) &&
                                                                SUCCESS == zend_hash_find(Z_ARRVAL_PP(sub), ZEND_STRS("free"), (void *) &zfree)) {
-                                                       convert_to_string(*zused);
-                                                       convert_to_string(*zfree);
-                                                       php_info_print_table_row(4, provider.str, ident.str, Z_STRVAL_PP(zused), Z_STRVAL_PP(zfree));
+                                                       zval *used = http_zsep(IS_STRING, *zused);
+                                                       zval *free = http_zsep(IS_STRING, *zfree);
+                                                       php_info_print_table_row(4, provider.str, ident.str, Z_STRVAL_P(used), Z_STRVAL_P(free));
+                                                       zval_ptr_dtor(&used);
+                                                       zval_ptr_dtor(&free);
                                                } else {
                                                        php_info_print_table_row(4, provider.str, ident.str, "0", "0");
                                                }
index b54da54..4fa8c3d 100644 (file)
@@ -549,15 +549,6 @@ PHP_HTTP_API STATUS _http_parse_params_ex(const char *param, int flags, http_par
                                                goto failure;
                                                break;
                                        
-                                       case '=':
-                                               if (key) {
-                                                       keylen = c - key;
-                                                       st = ST_VALUE;
-                                               } else {
-                                                       goto failure;
-                                               }
-                                               break;
-                                       
                                        case ' ':
                                                if (key) {
                                                        keylen = c - key;
@@ -574,7 +565,32 @@ PHP_HTTP_API STATUS _http_parse_params_ex(const char *param, int flags, http_par
                                                }
                                                break;
                                        
+                                       case ':':
+                                               if (!(flags & HTTP_PARAMS_COLON_SEPARATOR)) {
+                                                       goto not_separator;
+                                               }
+                                               if (key) {
+                                                       keylen = c - key;
+                                                       st = ST_VALUE;
+                                               } else {
+                                                       goto failure;
+                                               }
+                                               break;
+                                               
+                                       case '=':
+                                               if (flags & HTTP_PARAMS_COLON_SEPARATOR) {
+                                                       goto not_separator;
+                                               }
+                                               if (key) {
+                                                       keylen = c - key;
+                                                       st = ST_VALUE;
+                                               } else {
+                                                       goto failure;
+                                               }
+                                               break;
+                                       
                                        default:
+                                       not_separator:
                                                if (!key) {
                                                        key = c;
                                                }
@@ -666,10 +682,7 @@ int apply_array_append_func(void *pDest HTTP_ZAPI_HASH_TSRMLS_DC, int num_args,
                
                ZVAL_ADDREF(*value);
                if (data) {
-                       if (Z_TYPE_PP(data) != IS_ARRAY) {
-                               convert_to_array(*data);
-                       }
-                       add_next_index_zval(*data, *value);
+                       add_next_index_zval(http_zset(IS_ARRAY, *data), *value);
                } else if (key) {
                        zend_hash_add(dst, key, hash_key->nKeyLength, value, sizeof(zval *), NULL);
                } else {
index 2f0d6c5..a9dd14c 100644 (file)
@@ -249,12 +249,9 @@ 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 = *tmp;
-                               convert_to_long_ex(&cpy);
-                               list->flags = Z_LVAL_PP(tmp);
-                               if (cpy != *tmp) {
-                                       zval_ptr_dtor(&cpy);
-                               }
+                               cpy = http_zsep(IS_LONG, *tmp);
+                               list->flags = Z_LVAL_P(cpy);
+                               zval_ptr_dtor(&cpy);
                                break;
                        default:
                                break;
@@ -269,8 +266,7 @@ 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 = *tmp;
-                               convert_to_long_ex(&cpy);
+                               cpy = http_zsep(IS_LONG, *tmp);
                                if (Z_LVAL_P(cpy)) {
                                        list->expires = Z_LVAL_P(cpy);
                                } else {
@@ -279,9 +275,7 @@ PHP_HTTP_API http_cookie_list *_http_cookie_list_fromstruct(http_cookie_list *li
                                                list->expires = expires;
                                        }
                                }
-                               if (cpy != *tmp) {
-                                       zval_ptr_dtor(&cpy);
-                               }
+                               zval_ptr_dtor(&cpy);
                                break;
                        default:
                                break;
index d072787..a78bb7b 100644 (file)
@@ -500,11 +500,10 @@ static php_stream_filter *http_filter_create(const char *name, zval *params, int
                                        }
                                default:
                                {
-                                       zval *orig = *tmp;
+                                       zval *num = http_zsep(IS_LONG, *tmp);
                                        
-                                       convert_to_long_ex(tmp);
-                                       flags |= (Z_LVAL_PP(tmp) & 0x0fffffff);
-                                       if (orig != *tmp) zval_ptr_dtor(tmp);
+                                       flags |= (Z_LVAL_P(num) & 0x0fffffff);
+                                       zval_ptr_dtor(&num);
                                }
                        }
                }
index 7b58cf7..94b62bf 100644 (file)
@@ -185,11 +185,12 @@ PHP_FUNCTION(http_build_str)
                \
                if (rs_array) { \
                        HashPosition pos; \
-                       zval **value; \
+                       zval **value_ptr; \
                         \
-                       FOREACH_VAL(pos, supported, value) { \
-                               convert_to_string_ex(value); \
-                               add_assoc_double(rs_array, Z_STRVAL_PP(value), 1.0); \
+                       FOREACH_VAL(pos, supported, value_ptr) { \
+                               zval *value = http_zsep(IS_STRING, *value_ptr); \
+                               add_assoc_double(rs_array, Z_STRVAL_P(value), 1.0); \
+                               zval_ptr_dtor(&value); \
                        } \
                } \
        } \
@@ -675,10 +676,9 @@ PHP_FUNCTION(http_parse_cookie)
        if (allowed_extras_array) {
                allowed_extras = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(allowed_extras_array)) + 1, sizeof(char *));
                FOREACH_VAL(pos, allowed_extras_array, entry) {
-                       ZVAL_ADDREF(*entry);
-                       convert_to_string_ex(entry);
-                       allowed_extras[i++] = estrndup(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry));
-                       zval_ptr_dtor(entry);
+                       zval *data = http_zsep(IS_STRING, *entry);
+                       allowed_extras[i++] = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data));
+                       zval_ptr_dtor(&data);
                }
        }
        
index 1da83ae..4c0d2f4 100644 (file)
@@ -501,12 +501,9 @@ 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 = *data;
-               convert_to_string_ex(&zvalue);
+               zvalue = http_zsep(IS_STRING, *data);
                result = (match_case ? strcmp(Z_STRVAL_P(zvalue), value) : strcasecmp(Z_STRVAL_P(zvalue), value)) ? 0 : 1;
-               if (zvalue != *data) {
-                       zval_ptr_dtor(&zvalue);
-               }
+               zval_ptr_dtor(&zvalue);
        }
        efree(name);
 
index 8845681..6d271ba 100644 (file)
@@ -526,7 +526,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;
+       zval *cpy = NULL;
 #ifdef WONKY
        ulong h = zend_hash_func(Z_STRVAL_P(member), Z_STRLEN_P(member) + 1);
 #else
@@ -538,8 +538,6 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va
        }
 #endif
        
-       cpy = value;
-       
 #ifdef WONKY
        switch (h)
 #else
@@ -548,26 +546,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_ex(&cpy);
+                       cpy = http_zsep(IS_LONG, value);
                        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_ex(&cpy);
+                       cpy = http_zsep(IS_DOUBLE, value);
                        msg->http.version = Z_DVAL_P(cpy);
                        break;
 
                case HTTP_MSG_PROPHASH_BODY:
                case HTTP_MSG_CHILD_PROPHASH_BODY:
-                       convert_to_string_ex(&cpy);
+                       cpy = http_zsep(IS_STRING, value);
                        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_ex(&cpy);
+                       cpy = http_zsep(IS_ARRAY, value);
                        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;
@@ -588,7 +586,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_ex(&cpy);
+                               cpy = http_zsep(IS_STRING, value);
                                STR_SET(msg->http.info.request.method, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)));
                        }
                        break;
@@ -596,7 +594,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_ex(&cpy);
+                               cpy = http_zsep(IS_STRING, value);
                                STR_SET(msg->http.info.request.url, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)));
                        }
                        break;
@@ -604,7 +602,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_ex(&cpy);
+                               cpy = http_zsep(IS_LONG, value);
                                msg->http.info.response.code = Z_LVAL_P(cpy);
                        }
                        break;
@@ -612,7 +610,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_ex(&cpy);
+                               cpy = http_zsep(IS_STRING, value);
                                STR_SET(msg->http.info.response.status, estrndup(Z_STRVAL_P(cpy), Z_STRLEN_P(cpy)));
                        }
                        break;
@@ -621,7 +619,7 @@ static void _http_message_object_write_prop(zval *object, zval *member, zval *va
                        zend_get_std_object_handlers()->write_property(object, member, value TSRMLS_CC);
                        break;
        }
-       if (cpy != value) {
+       if (cpy) {
                zval_ptr_dtor(&cpy);
        }
 }
index 5d636a3..4fc3986 100644 (file)
@@ -127,14 +127,14 @@ PHP_HTTP_API int _http_querystring_modify(zval *qarray, zval *params TSRMLS_DC)
        } else {
                int rv;
                zval array;
+               zval *qstring = http_zsep(IS_STRING, params);
                
                INIT_PZVAL(&array);
                array_init(&array);
                
-               ZVAL_ADDREF(params);
-               convert_to_string_ex(&params);
-               sapi_module.treat_data(PARSE_STRING, estrdup(Z_STRVAL_P(params)), &array TSRMLS_CC);
-               zval_ptr_dtor(&params);
+               sapi_module.treat_data(PARSE_STRING, estrdup(Z_STRVAL_P(qstring)), &array TSRMLS_CC);
+               zval_ptr_dtor(&qstring);
+               
                rv = http_querystring_modify_array(qarray, &array);
                zval_dtor(&array);
                return rv;
index 9c183f3..f47eecf 100644 (file)
@@ -285,10 +285,11 @@ static inline void _http_querystring_get(zval *this_ptr, int type, char *name, u
        zval **arrval, *qarray = zend_read_property(THIS_CE, getThis(), ZEND_STRS("queryArray")-1, 0 TSRMLS_CC);
                
        if ((Z_TYPE_P(qarray) == IS_ARRAY) && (SUCCESS == zend_hash_find(Z_ARRVAL_P(qarray), name, name_len + 1, (void *) &arrval))) {
-               RETVAL_ZVAL(*arrval, 1, 0);
-               
                if (type) {
-                       convert_to_type(type, return_value);
+                       zval *value = http_zsep(type, *arrval);
+                       RETVAL_ZVAL(value, 1, 1);
+               } else {
+                       RETVAL_ZVAL(*arrval, 1, 0);
                }
                        
                if (del && (SUCCESS == zend_hash_del(Z_ARRVAL_P(qarray), name, name_len + 1))) {
index 42ef30f..4ebbc2f 100644 (file)
@@ -223,6 +223,9 @@ static inline zval *_http_request_option_ex(http_request *request, HashTable *op
 #define http_request_option_cache_ex(r, k, kl, h, z) _http_request_option_cache_ex((r), (k), (kl), (h), (z) TSRMLS_CC)
 static inline zval *_http_request_option_cache_ex(http_request *r, char *key, size_t keylen, ulong h, zval *opt TSRMLS_DC);
 
+#define http_request_cookies_enabled(r) _http_request_cookies_enabled((r))
+static inline int _http_request_cookies_enabled(http_request *r);
+
 static size_t http_curl_read_callback(void *, size_t, size_t, void *);
 static int http_curl_progress_callback(void *, double, double, double, double);
 static int http_curl_raw_callback(CURL *, curl_infotype, char *, size_t, void *);
@@ -385,7 +388,7 @@ PHP_HTTP_API STATUS _http_request_enable_cookies(http_request *request)
        TSRMLS_FETCH_FROM_CTX(request->tsrm_ls);
        
        HTTP_CHECK_CURL_INIT(request->ch, http_curl_init_ex(request->ch, request), initialized = 0);
-       if (initialized && CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIEFILE, "")) {
+       if (initialized && (http_request_cookies_enabled(request) || (CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIEFILE, "")))) {
                return SUCCESS;
        }
        http_error(HE_WARNING, HTTP_E_REQUEST, "Could not enable cookies for this session");
@@ -400,22 +403,29 @@ PHP_HTTP_API STATUS _http_request_reset_cookies(http_request *request, int sessi
        TSRMLS_FETCH_FROM_CTX(request->tsrm_ls);
        
        HTTP_CHECK_CURL_INIT(request->ch, http_curl_init_ex(request->ch, request), initialized = 0);
-       if (session_only) {
-#if HTTP_CURL_VERSION(7,15,4)
-               if (initialized && CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "SESS")) {
-                       return SUCCESS;
+       if (initialized) {
+               if (!http_request_cookies_enabled(request)) {
+                       if (SUCCESS != http_request_enable_cookies(request)) {
+                               return FAILURE;
+                       }
                }
+               if (session_only) {
+#if HTTP_CURL_VERSION(7,15,4)
+                       if (CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "SESS")) {
+                               return SUCCESS;
+                       }
 #else
-               http_error(HE_WARNING, HTTP_E_REQUEST, "Could not reset session cookies (need libcurl >= v7.15.4)");
+                       http_error(HE_WARNING, HTTP_E_REQUEST, "Could not reset session cookies (need libcurl >= v7.15.4)");
 #endif
-       } else {
+               } else {
 #if HTTP_CURL_VERSION(7,14,1)
-               if (initialized && CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "ALL")) {
-                       return SUCCESS;
-               }
+                       if (CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "ALL")) {
+                               return SUCCESS;
+                       }
 #else
-               http_error(HE_WARNING, HTTP_E_REQUEST, "Could not reset cookies (need libcurl >= v7.14.1)");
+                       http_error(HE_WARNING, HTTP_E_REQUEST, "Could not reset cookies (need libcurl >= v7.14.1)");
 #endif
+               }
        }
        return FAILURE;
 }
@@ -427,13 +437,18 @@ PHP_HTTP_API STATUS _http_request_flush_cookies(http_request *request)
        TSRMLS_FETCH_FROM_CTX(request->tsrm_ls);
        
        HTTP_CHECK_CURL_INIT(request->ch, http_curl_init_ex(request->ch, request), initialized = 0);
+       if (initialized) {
+               if (!http_request_cookies_enabled(request)) {
+                       return FAILURE;
+               }
 #if HTTP_CURL_VERSION(7,17,1)
-       if (initialized && CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "FLUSH")) {
-               return SUCCESS;
-       }
+               if (CURLE_OK == curl_easy_setopt(request->ch, CURLOPT_COOKIELIST, "FLUSH")) {
+                       return SUCCESS;
+               }
 #else
-       http_error(HE_WARNING, HTTP_E_REQUEST, "Could not flush cookies (need libcurl >= v7.17.1)");
+               http_error(HE_WARNING, HTTP_E_REQUEST, "Could not flush cookies (need libcurl >= v7.17.1)");
 #endif
+       }
        return FAILURE;
 }
 
@@ -655,20 +670,15 @@ 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 = *prs, *pre_cpy = *pre;
+                                       zval *prs_cpy = http_zsep(IS_LONG, *prs);
+                                       zval *pre_cpy = http_zsep(IS_LONG, *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);
                                        }
-                                       if (prs_cpy != *prs) {
-                                               zval_ptr_dtor(&prs_cpy);
-                                       }
-                                       if (pre_cpy != *pre) {
-                                               zval_ptr_dtor(&pre_cpy);
-                                       }
+                                       zval_ptr_dtor(&prs_cpy);
+                                       zval_ptr_dtor(&pre_cpy);
                                }
                        }
                }
@@ -760,19 +770,14 @@ 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 = *rb, *rel = *re;
+                                                       zval *rbl = http_zsep(IS_LONG, *rb);
+                                                       zval *rel = http_zsep(IS_LONG, *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));
                                                        }
-                                                       if (rbl != *rb) {
-                                                               zval_ptr_dtor(&rbl);
-                                                       }
-                                                       if (rel != *re) {
-                                                               zval_ptr_dtor(&rel);
-                                                       }
+                                                       zval_ptr_dtor(&rbl);
+                                                       zval_ptr_dtor(&rel);
                                                }
                                        }
                                }
@@ -805,13 +810,14 @@ PHP_HTTP_API STATUS _http_request_prepare(http_request *request, HashTable *opti
                FOREACH_KEYVAL(pos, zoption, header_key, header_val) {
                        if (header_key.type == HASH_KEY_IS_STRING) {
                                char header[1024];
+                               zval *header_cpy = http_zsep(IS_STRING, *header_val);
                                
-                               convert_to_string_ex(header_val);
                                if (!strcasecmp(header_key.str, "range")) {
                                        range_req = 1;
                                }
-                               snprintf(header, sizeof(header), "%s: %s", header_key.str, Z_STRVAL_PP(header_val));
+                               snprintf(header, sizeof(header), "%s: %s", header_key.str, Z_STRVAL_P(header_cpy));
                                request->_cache.headers = curl_slist_append(request->_cache.headers, header);
+                               zval_ptr_dtor(&header_cpy);
                        }
                }
        }
@@ -864,12 +870,9 @@ 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 = *cookie_val;
-                                               convert_to_string_ex(&val);
+                                               zval *val = http_zsep(IS_STRING, *cookie_val);
                                                phpstr_appendf(&request->_cache.cookies, "%s=%s; ", cookie_key.str, Z_STRVAL_P(val));
-                                               if (val != *cookie_val) {
-                                                       zval_ptr_dtor(&val);
-                                               }
+                                               zval_ptr_dtor(&val);
                                        }
                                }
                                
@@ -1215,15 +1218,13 @@ 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)) {
-                       zval *copy;
+                       zval *option, *cached;
                        
-                       MAKE_STD_ZVAL(copy);
-                       ZVAL_ZVAL(copy, *zoption, 1, 0);
+                       option = http_zsep(type, *zoption);
+                       cached = http_request_option_cache_ex(r, key, keylen, h, option);
                        
-                       convert_to_type(type, copy);
-                       http_request_option_cache_ex(r, key, keylen, h, copy);
-                       zval_ptr_dtor(&copy);
-                       return copy;
+                       zval_ptr_dtor(&option);
+                       return cached;
                }
        }
        
@@ -1246,6 +1247,18 @@ static inline zval *_http_request_option_cache_ex(http_request *r, char *key, si
 }
 /* }}} */
 
+/* {{{ static inline int http_request_cookies_enabled(http_request *) */
+static inline int _http_request_cookies_enabled(http_request *request) {
+       http_request_storage *st;
+       
+       if (request->ch && (st = http_request_storage_get(request->ch)) && st->cookiestore) {
+               /* cookies are enabled */
+               return 1;
+       }
+       return 0;
+}
+/* }}} */
+
 #endif /* HTTP_HAVE_CURL */
 
 /*
index f2d5f56..bb969e6 100644 (file)
@@ -43,28 +43,25 @@ PHP_HTTP_API http_request_body *_http_request_body_fill(http_request_body *body,
 {
        if (files && (zend_hash_num_elements(files) > 0)) {
                HashKey key = initHashKey(0);
-               zval **data;
+               zval **data_ptr;
                HashPosition pos;
                struct curl_httppost *http_post_data[2] = {NULL, NULL};
 
                /* normal data */
                if (fields) {
-                       FOREACH_HASH_KEYVAL(pos, fields, key, data) {
+                       FOREACH_HASH_KEYVAL(pos, fields, key, data_ptr) {
                                if (key.type == HASH_KEY_IS_STRING) {
                                        CURLcode err;
-                                       zval *orig = *data;
+                                       zval *data = http_zsep(IS_STRING, *data_ptr);
                                        
-                                       convert_to_string_ex(data);
                                        err = curl_formadd(&http_post_data[0], &http_post_data[1],
                                                CURLFORM_COPYNAME,                      key.str,
-                                               CURLFORM_COPYCONTENTS,          Z_STRVAL_PP(data),
-                                               CURLFORM_CONTENTSLENGTH,        (long) Z_STRLEN_PP(data),
+                                               CURLFORM_COPYCONTENTS,          Z_STRVAL_P(data),
+                                               CURLFORM_CONTENTSLENGTH,        (long) Z_STRLEN_P(data),
                                                CURLFORM_END
                                        );
                                        
-                                       if (orig != *data) {
-                                               zval_ptr_dtor(data);
-                                       }
+                                       zval_ptr_dtor(&data);
                                        
                                        if (CURLE_OK != err) {
                                                http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post fields: %s", curl_easy_strerror(err));
@@ -76,43 +73,41 @@ PHP_HTTP_API http_request_body *_http_request_body_fill(http_request_body *body,
                }
 
                /* file data */
-               FOREACH_HASH_VAL(pos, files, data) {
-                       zval **file, **type, **name;
+               FOREACH_HASH_VAL(pos, files, data_ptr) {
+                       zval **file_ptr, **type_ptr, **name_ptr;
                        
-                       if (Z_TYPE_PP(data) != IS_ARRAY) {
+                       if (Z_TYPE_PP(data_ptr) != IS_ARRAY) {
                                http_error(HE_NOTICE, HTTP_E_INVALID_PARAM, "Unrecognized type of post file array entry");
-                       } else if (     SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "name", sizeof("name"), (void *) &name) ||
-                                               SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "type", sizeof("type"), (void *) &type) ||
-                                               SUCCESS != zend_hash_find(Z_ARRVAL_PP(data), "file", sizeof("file"), (void *) &file)) {
+                       } else if (     SUCCESS != zend_hash_find(Z_ARRVAL_PP(data_ptr), "name", sizeof("name"), (void *) &name_ptr) ||
+                                               SUCCESS != zend_hash_find(Z_ARRVAL_PP(data_ptr), "type", sizeof("type"), (void *) &type_ptr) ||
+                                               SUCCESS != zend_hash_find(Z_ARRVAL_PP(data_ptr), "file", sizeof("file"), (void *) &file_ptr)) {
                                http_error(HE_NOTICE, HTTP_E_INVALID_PARAM, "Post file array entry misses either 'name', 'type' or 'file' entry");
                        } else {
                                CURLcode err;
                                const char *path;
-                               zval *ofile = *file, *otype = *type, *oname = *name;
-                               
-                               convert_to_string_ex(file);
-                               convert_to_string_ex(type);
-                               convert_to_string_ex(name);
+                               zval *file = http_zsep(IS_STRING, *file_ptr);
+                               zval *type = http_zsep(IS_STRING, *type_ptr);
+                               zval *name = http_zsep(IS_STRING, *name_ptr);
                                
-                               HTTP_CHECK_OPEN_BASEDIR(Z_STRVAL_PP(file), curl_formfree(http_post_data[0]); return NULL);
+                               HTTP_CHECK_OPEN_BASEDIR(Z_STRVAL_P(file), curl_formfree(http_post_data[0]); return NULL);
                                
                                /* this is blatant but should be sufficient for most cases */
-                               if (strncasecmp(Z_STRVAL_PP(file), "file://", lenof("file://"))) {
-                                       path = Z_STRVAL_PP(file);
+                               if (strncasecmp(Z_STRVAL_P(file), "file://", lenof("file://"))) {
+                                       path = Z_STRVAL_P(file);
                                } else {
-                                       path = Z_STRVAL_PP(file) + lenof("file://");
+                                       path = Z_STRVAL_P(file) + lenof("file://");
                                }
                                
                                err = curl_formadd(&http_post_data[0], &http_post_data[1],
-                                       CURLFORM_COPYNAME,              Z_STRVAL_PP(name),
+                                       CURLFORM_COPYNAME,              Z_STRVAL_P(name),
                                        CURLFORM_FILE,                  path,
-                                       CURLFORM_CONTENTTYPE,   Z_STRVAL_PP(type),
+                                       CURLFORM_CONTENTTYPE,   Z_STRVAL_P(type),
                                        CURLFORM_END
                                );
                                
-                               if (ofile != *file) zval_ptr_dtor(file);
-                               if (otype != *type) zval_ptr_dtor(type);
-                               if (oname != *name) zval_ptr_dtor(name);
+                               zval_ptr_dtor(&file);
+                               zval_ptr_dtor(&type);
+                               zval_ptr_dtor(&name);
                                
                                if (CURLE_OK != err) {
                                        http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Could not encode post files: %s", curl_easy_strerror(err));
index c72d908..1795e37 100644 (file)
@@ -1176,13 +1176,10 @@ PHP_METHOD(HttpRequest, setQueryData)
                zend_update_property_string(THIS_CE, getThis(), ZEND_STRS("queryData")-1, query_data TSRMLS_CC);
                efree(query_data);
        } else {
-               zval *orig = qdata;
+               zval *data = http_zsep(IS_STRING, qdata);
                
-               convert_to_string_ex(&qdata);
-               zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("queryData")-1, Z_STRVAL_P(qdata), Z_STRLEN_P(qdata) TSRMLS_CC);
-               if (orig != qdata) {
-                       zval_ptr_dtor(&qdata);
-               }
+               zend_update_property_stringl(THIS_CE, getThis(), ZEND_STRS("queryData")-1, Z_STRVAL_P(data), Z_STRLEN_P(data) TSRMLS_CC);
+               zval_ptr_dtor(&data);
        }
        RETURN_TRUE;
 }
@@ -1587,10 +1584,9 @@ PHP_METHOD(HttpRequest, getResponseCookies)
                                if (allowed_extras_array) {
                                        allowed_extras = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(allowed_extras_array)) + 1, sizeof(char *));
                                        FOREACH_VAL(pos, allowed_extras_array, entry) {
-                                               ZVAL_ADDREF(*entry);
-                                               convert_to_string_ex(entry);
-                                               allowed_extras[i++] = estrndup(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry));
-                                               zval_ptr_dtor(entry);
+                                               zval *data = http_zsep(IS_STRING, *entry);
+                                               allowed_extras[i++] = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data));
+                                               zval_ptr_dtor(&data);
                                        }
                                }
                                
@@ -1602,9 +1598,9 @@ PHP_METHOD(HttpRequest, getResponseCookies)
                                                        zval **single_header;
                                                        
                                                        FOREACH_VAL(pos2, *header, single_header) {
-                                                               ZVAL_ADDREF(*single_header);
-                                                               convert_to_string_ex(single_header);
-                                                               if (http_parse_cookie_ex(&list, Z_STRVAL_PP(single_header), flags, allowed_extras)) {
+                                                               zval *data = http_zsep(IS_STRING, *single_header);
+                                                               
+                                                               if (http_parse_cookie_ex(&list, Z_STRVAL_P(data), flags, allowed_extras)) {
                                                                        zval *cookie;
                                                                        
                                                                        MAKE_STD_ZVAL(cookie);
@@ -1613,12 +1609,11 @@ PHP_METHOD(HttpRequest, getResponseCookies)
                                                                        add_next_index_zval(return_value, cookie);
                                                                        http_cookie_list_dtor(&list);
                                                                }
-                                                               zval_ptr_dtor(single_header);
+                                                               zval_ptr_dtor(&data);
                                                        }
                                                } else {
-                                                       ZVAL_ADDREF(*header);
-                                                       convert_to_string_ex(header);
-                                                       if (http_parse_cookie_ex(&list, Z_STRVAL_PP(header), flags, allowed_extras)) {
+                                                       zval *data = http_zsep(IS_STRING, *header);
+                                                       if (http_parse_cookie_ex(&list, Z_STRVAL_P(data), flags, allowed_extras)) {
                                                                zval *cookie;
                                                                
                                                                MAKE_STD_ZVAL(cookie);
@@ -1627,7 +1622,7 @@ PHP_METHOD(HttpRequest, getResponseCookies)
                                                                add_next_index_zval(return_value, cookie);
                                                                http_cookie_list_dtor(&list);
                                                        }
-                                                       zval_ptr_dtor(header);
+                                                       zval_ptr_dtor(&data);
                                                }
                                        }
                                }
index ed634af..e638353 100644 (file)
@@ -299,13 +299,8 @@ PHP_METHOD(HttpResponse, getCache)
        NO_ARGS;
 
        if (return_value_used) {
-               zval *cache_p, *cache = convert_to_type_ex(IS_BOOL, *zend_std_get_static_property(THIS_CE, ZEND_STRS("cache")-1, 0 TSRMLS_CC), &cache_p);
-               
-               RETVAL_ZVAL(cache, 1, 0);
-
-               if (cache_p) {
-                       zval_ptr_dtor(&cache_p);
-               }
+               zval *cache = http_zsep(IS_BOOL, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("cache")-1, 0 TSRMLS_CC)));
+               RETVAL_ZVAL(cache, 1, 1);
        }
 }
 /* }}}*/
@@ -331,13 +326,8 @@ PHP_METHOD(HttpResponse, getGzip)
        NO_ARGS;
 
        if (return_value_used) {
-               zval *gzip_p, *gzip = convert_to_type_ex(IS_BOOL, *zend_std_get_static_property(THIS_CE, ZEND_STRS("gzip")-1, 0 TSRMLS_CC), &gzip_p);
-               
-               RETVAL_ZVAL(gzip, 1, 0);
-
-               if (gzip_p) {
-                       zval_ptr_dtor(&gzip_p);
-               }
+               zval *gzip = http_zsep(IS_BOOL, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("gzip")-1, 0 TSRMLS_CC)));
+               RETVAL_ZVAL(gzip, 1, 1);
        }
 }
 /* }}} */
@@ -373,13 +363,8 @@ PHP_METHOD(HttpResponse, getCacheControl)
        NO_ARGS;
 
        if (return_value_used) {
-               zval *ccontrol_p, *ccontrol = convert_to_type_ex(IS_STRING, *zend_std_get_static_property(THIS_CE, ZEND_STRS("cacheControl")-1, 0 TSRMLS_CC), &ccontrol_p);
-               
-               RETVAL_ZVAL(ccontrol, 1, 0);
-
-               if (ccontrol_p) {
-                       zval_ptr_dtor(&ccontrol_p);
-               }
+               zval *cctl = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("cacheControl")-1, 0 TSRMLS_CC)));
+               RETVAL_ZVAL(cctl, 1, 1);
        }
 }
 /* }}} */
@@ -407,13 +392,8 @@ PHP_METHOD(HttpResponse, getContentType)
        NO_ARGS;
 
        if (return_value_used) {
-               zval *ctype_p, *ctype = convert_to_type_ex(IS_STRING, *zend_std_get_static_property(THIS_CE, ZEND_STRS("contentType")-1, 0 TSRMLS_CC), &ctype_p);
-               
-               RETVAL_ZVAL(ctype, 1, 0);
-
-               if (ctype_p) {
-                       zval_ptr_dtor(&ctype_p);
-               }
+               zval *ctype = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("contentType")-1, 0 TSRMLS_CC)));
+               RETVAL_ZVAL(ctype, 1, 1);
        }
 }
 /* }}} */
@@ -491,13 +471,8 @@ PHP_METHOD(HttpResponse, getContentDisposition)
        NO_ARGS;
 
        if (return_value_used) {
-               zval *cd_p, *cd = convert_to_type_ex(IS_STRING, *zend_std_get_static_property(THIS_CE, ZEND_STRS("contentDisposition")-1, 0 TSRMLS_CC), &cd_p);
-               
-               RETVAL_ZVAL(cd, 1, 0);
-
-               if (cd_p) {
-                       zval_ptr_dtor(&cd_p);
-               }
+               zval *cdisp = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("contentDisposition")-1, 0 TSRMLS_CC)));
+               RETVAL_ZVAL(cdisp, 1, 1);
        }
 }
 /* }}} */
@@ -524,13 +499,8 @@ PHP_METHOD(HttpResponse, getETag)
        NO_ARGS;
 
        if (return_value_used) {
-               zval *etag_p, *etag = convert_to_type_ex(IS_STRING, *zend_std_get_static_property(THIS_CE, ZEND_STRS("eTag")-1, 0 TSRMLS_CC), &etag_p);
-               
-               RETVAL_ZVAL(etag, 1, 0);
-
-               if (etag_p) {
-                       zval_ptr_dtor(&etag_p);
-               }
+               zval *etag = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("eTag")-1, 0 TSRMLS_CC)));
+               RETVAL_ZVAL(etag, 1, 1);
        }
 }
 /* }}} */
@@ -556,13 +526,8 @@ PHP_METHOD(HttpResponse, getLastModified)
        NO_ARGS;
        
        if (return_value_used) {
-               zval *lm_p, *lm = convert_to_type_ex(IS_LONG, *zend_std_get_static_property(THIS_CE, ZEND_STRS("lastModified")-1, 0 TSRMLS_CC), &lm_p);
-               
-               RETVAL_ZVAL(lm, 1, 0);
-
-               if (lm_p) {
-                       zval_ptr_dtor(&lm_p);
-               }
+               zval *lmod = http_zsep(IS_LONG, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("lastModified")-1, 0 TSRMLS_CC)));
+               RETVAL_ZVAL(lmod, 1, 1);
        }
 }
 /* }}} */
@@ -587,13 +552,8 @@ PHP_METHOD(HttpResponse, getThrottleDelay)
        NO_ARGS;
 
        if (return_value_used) {
-               zval *delay_p, *delay = convert_to_type_ex(IS_DOUBLE, *zend_std_get_static_property(THIS_CE, ZEND_STRS("throttleDelay")-1, 0 TSRMLS_CC), &delay_p);
-               
-               RETVAL_ZVAL(delay, 1, 0);
-
-               if (delay_p) {
-                       zval_ptr_dtor(&delay_p);
-               }
+               zval *tdel = http_zsep(IS_DOUBLE, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("throttleDelay")-1, 0 TSRMLS_CC)));
+               RETVAL_ZVAL(tdel, 1, 1);
        }
 }
 /* }}} */
@@ -618,13 +578,8 @@ PHP_METHOD(HttpResponse, getBufferSize)
        NO_ARGS;
 
        if (return_value_used) {
-               zval *size_p, *size = convert_to_type_ex(IS_LONG, *zend_std_get_static_property(THIS_CE, ZEND_STRS("bufferSize")-1, 0 TSRMLS_CC), &size_p);
-               
-               RETVAL_ZVAL(size, 1, 0);
-
-               if (size_p) {
-                       zval_ptr_dtor(&size_p);
-               }
+               zval *bsize = http_zsep(IS_LONG, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("bufferSize")-1, 0 TSRMLS_CC)));
+               RETVAL_ZVAL(bsize, 1, 1);
        }
 }
 /* }}} */
@@ -640,7 +595,7 @@ PHP_METHOD(HttpResponse, setData)
                RETURN_FALSE;
        }
        if (Z_TYPE_P(the_data) != IS_STRING) {
-               convert_to_string_ex(&the_data);
+               convert_to_string(the_data);
        }
 
        if (    (SUCCESS != zend_update_static_property(THIS_CE, ZEND_STRS("data")-1, the_data TSRMLS_CC)) ||
@@ -713,13 +668,8 @@ PHP_METHOD(HttpResponse, getStream)
        NO_ARGS;
 
        if (return_value_used) {
-               zval *stream_p;
-               
-               RETVAL_RESOURCE(Z_LVAL_P(convert_to_type_ex(IS_LONG, *zend_std_get_static_property(THIS_CE, ZEND_STRS("stream")-1, 0 TSRMLS_CC), &stream_p)));
-
-               if (stream_p) {
-                       zval_ptr_dtor(&stream_p);
-               }
+               zval *stream = http_zsep(IS_LONG, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("stream")-1, 0 TSRMLS_CC)));
+               RETVAL_RESOURCE(Z_LVAL_P(stream));
        }
 }
 /* }}} */
@@ -762,13 +712,8 @@ PHP_METHOD(HttpResponse, getFile)
        NO_ARGS;
 
        if (return_value_used) {
-               zval *the_file_p, *the_file = convert_to_type_ex(IS_STRING, *zend_std_get_static_property(THIS_CE, ZEND_STRS("file")-1, 0 TSRMLS_CC), &the_file_p);
-               
-               RETVAL_ZVAL(the_file, 1, 0);
-
-               if (the_file_p) {
-                       zval_ptr_dtor(&the_file_p);
-               }
+               zval *file = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("file")-1, 0 TSRMLS_CC)));
+               RETVAL_ZVAL(file, 1, 1);
        }
 }
 /* }}} */
@@ -796,14 +741,15 @@ PHP_METHOD(HttpResponse, send)
 
        /* capture mode */
        if (i_zend_is_true(*zend_std_get_static_property(THIS_CE, ZEND_STRS("catch")-1, 0 TSRMLS_CC))) {
-               zval *etag_p, *the_data;
+               zval *zetag, *the_data;
 
                MAKE_STD_ZVAL(the_data);
                php_ob_get_buffer(the_data TSRMLS_CC);
                zend_update_static_property(THIS_CE, ZEND_STRS("data")-1, the_data TSRMLS_CC);
                ZVAL_LONG(*zend_std_get_static_property(THIS_CE, ZEND_STRS("mode")-1, 0 TSRMLS_CC), SEND_DATA);
 
-               if (!Z_STRLEN_P(convert_to_type_ex(IS_STRING, *zend_std_get_static_property(THIS_CE, ZEND_STRS("eTag")-1, 0 TSRMLS_CC), &etag_p))) {
+               zetag = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("eTag")-1, 0 TSRMLS_CC)));
+               if (!Z_STRLEN_P(zetag)) {
                        char *etag = http_etag(Z_STRVAL_P(the_data), Z_STRLEN_P(the_data), SEND_DATA);
                        if (etag) {
                                zend_update_static_property_string(THIS_CE, ZEND_STRS("eTag")-1, etag TSRMLS_CC);
@@ -811,10 +757,7 @@ PHP_METHOD(HttpResponse, send)
                        }
                }
                zval_ptr_dtor(&the_data);
-               
-               if (etag_p) {
-                       zval_ptr_dtor(&etag_p);
-               }
+               zval_ptr_dtor(&zetag);
 
                clean_ob = 1;
        }
@@ -828,11 +771,11 @@ PHP_METHOD(HttpResponse, send)
 
        /* caching */
        if (i_zend_is_true(*zend_std_get_static_property(THIS_CE, ZEND_STRS("cache")-1, 0 TSRMLS_CC))) {
-               zval *cctl, *cctl_p, *etag, *etag_p, *lmod, *lmod_p;
+               zval *cctl, *etag, *lmod;
                
-               etag = convert_to_type_ex(IS_STRING, *zend_std_get_static_property(THIS_CE, ZEND_STRS("eTag")-1, 0 TSRMLS_CC), &etag_p);
-               lmod = convert_to_type_ex(IS_LONG, *zend_std_get_static_property(THIS_CE, ZEND_STRS("lastModified")-1, 0 TSRMLS_CC), &lmod_p);
-               cctl = convert_to_type_ex(IS_STRING, *zend_std_get_static_property(THIS_CE, ZEND_STRS("cacheControl")-1, 0 TSRMLS_CC), &cctl_p);
+               lmod = http_zsep(IS_LONG, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("lastModified")-1, 0 TSRMLS_CC)));
+               etag = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("eTag")-1, 0 TSRMLS_CC)));
+               cctl = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("cacheControl")-1, 0 TSRMLS_CC)));
                
                if (Z_LVAL_P(lmod) || Z_STRLEN_P(etag)) {
                        if (Z_STRLEN_P(cctl)) {
@@ -848,14 +791,14 @@ PHP_METHOD(HttpResponse, send)
                        }
                }
                
-               if (etag_p) zval_ptr_dtor(&etag_p);
-               if (lmod_p) zval_ptr_dtor(&lmod_p);
-               if (cctl_p) zval_ptr_dtor(&cctl_p);
+               zval_ptr_dtor(&etag);
+               zval_ptr_dtor(&lmod);
+               zval_ptr_dtor(&cctl);
        }
 
        /* content type */
        {
-               zval *ctype_p, *ctype = convert_to_type_ex(IS_STRING, *zend_std_get_static_property(THIS_CE, ZEND_STRS("contentType")-1, 0 TSRMLS_CC), &ctype_p);
+               zval *ctype = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("contentType")-1, 0 TSRMLS_CC)));
                if (Z_STRLEN_P(ctype)) {
                        http_send_content_type(Z_STRVAL_P(ctype), Z_STRLEN_P(ctype));
                } else {
@@ -868,30 +811,26 @@ PHP_METHOD(HttpResponse, send)
                                http_send_content_type("application/x-octetstream", lenof("application/x-octetstream"));
                        }
                }
-               if (ctype_p) {
-                       zval_ptr_dtor(&ctype_p);
-               }
+               zval_ptr_dtor(&ctype);
        }
 
        /* content disposition */
        {
-               zval *cd_p, *cd = convert_to_type_ex(IS_STRING, *zend_std_get_static_property(THIS_CE, ZEND_STRS("contentDisposition")-1, 0 TSRMLS_CC), &cd_p);
+               zval *cd = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("contentDisposition")-1, 0 TSRMLS_CC)));
                if (Z_STRLEN_P(cd)) {
                        http_send_header_ex("Content-Disposition", lenof("Content-Disposition"), Z_STRVAL_P(cd), Z_STRLEN_P(cd), 1, NULL);
                }
-               if (cd_p) {
-                       zval_ptr_dtor(&cd_p);
-               }
+               zval_ptr_dtor(&cd);
        }
 
        /* throttling */
        {
-               zval *bsize_p, *bsize = convert_to_type_ex(IS_LONG, *zend_std_get_static_property(THIS_CE, ZEND_STRS("bufferSize")-1, 0 TSRMLS_CC), &bsize_p);
-               zval *delay_p, *delay = convert_to_type_ex(IS_DOUBLE, *zend_std_get_static_property(THIS_CE, ZEND_STRS("throttleDelay")-1, 0 TSRMLS_CC), &delay_p);
+               zval *bsize = http_zsep(IS_LONG, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("bufferSize")-1, 0 TSRMLS_CC)));
+               zval *delay = http_zsep(IS_DOUBLE, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("throttleDelay")-1, 0 TSRMLS_CC)));
                HTTP_G->send.buffer_size    = Z_LVAL_P(bsize);
                HTTP_G->send.throttle_delay = Z_DVAL_P(delay);
-               if (bsize_p) zval_ptr_dtor(&bsize_p);
-               if (delay_p) zval_ptr_dtor(&delay_p);
+               zval_ptr_dtor(&bsize);
+               zval_ptr_dtor(&delay);
        }
 
        /* gzip */
@@ -901,28 +840,28 @@ PHP_METHOD(HttpResponse, send)
        switch (Z_LVAL_P(*zend_std_get_static_property(THIS_CE, ZEND_STRS("mode")-1, 0 TSRMLS_CC))) {
                case SEND_DATA:
                {
-                       zval *zdata_p, *zdata = convert_to_type_ex(IS_STRING, *zend_std_get_static_property(THIS_CE, ZEND_STRS("data")-1, 0 TSRMLS_CC), &zdata_p);
+                       zval *zdata = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("data")-1, 0 TSRMLS_CC)));
                        RETVAL_SUCCESS(http_send_data(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)));
-                       if (zdata_p) zval_ptr_dtor(&zdata_p);
+                       zval_ptr_dtor(&zdata);
                        return;
                }
 
                case SEND_RSRC:
                {
                        php_stream *the_real_stream;
-                       zval *the_stream_p, *the_stream = convert_to_type_ex(IS_LONG, *zend_std_get_static_property(THIS_CE, ZEND_STRS("stream")-1, 0 TSRMLS_CC), &the_stream_p);
+                       zval *the_stream = http_zsep(IS_LONG, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("stream")-1, 0 TSRMLS_CC)));
                        the_stream->type = IS_RESOURCE;
                        php_stream_from_zval(the_real_stream, &the_stream);
                        RETVAL_SUCCESS(http_send_stream(the_real_stream));
-                       if (the_stream_p) zval_ptr_dtor(&the_stream_p);
+                       zval_ptr_dtor(&the_stream);
                        return;
                }
 
                default:
                {
-                       zval *file_p;
-                       RETVAL_SUCCESS(http_send_file(Z_STRVAL_P(convert_to_type_ex(IS_STRING, *zend_std_get_static_property(THIS_CE, ZEND_STRS("file")-1, 0 TSRMLS_CC), &file_p))));
-                       if (file_p) zval_ptr_dtor(&file_p);
+                       zval *file = http_zsep(IS_STRING, *(zend_std_get_static_property(THIS_CE, ZEND_STRS("file")-1, 0 TSRMLS_CC)));
+                       RETVAL_SUCCESS(http_send_file(Z_STRVAL_P(file)));
+                       zval_ptr_dtor(&file);
                        return;
                }
        }
index ef8bf2d..4f97dac 100644 (file)
@@ -203,27 +203,21 @@ PHP_HTTP_API void _http_send_header_zval_ex(const char *name, size_t name_len, z
                http_hide_header_ex(name, name_len);
        } else if (Z_TYPE_PP(val) == IS_ARRAY || Z_TYPE_PP(val) == IS_OBJECT) {
                zend_bool first = replace;
-               zval **data;
+               zval **data_ptr;
                HashPosition pos;
                
-               FOREACH_HASH_VAL(pos, HASH_OF(*val), data) {
-                       zval *orig = *data;
+               FOREACH_HASH_VAL(pos, HASH_OF(*val), data_ptr) {
+                       zval *data = http_zsep(IS_STRING, *data_ptr);
                        
-                       convert_to_string_ex(data);
-                       http_send_header_ex(name, name_len, Z_STRVAL_PP(data), Z_STRLEN_PP(data), first, NULL);
-                       if (orig != *data) {
-                               zval_ptr_dtor(data);
-                       }
+                       http_send_header_ex(name, name_len, Z_STRVAL_P(data), Z_STRLEN_P(data), first, NULL);
+                       zval_ptr_dtor(&data);
                        first = 0;
                }
        } else {
-               zval *orig = *val;
+               zval *data = http_zsep(IS_STRING, *val);
                
-               convert_to_string_ex(val);
-               http_send_header_ex(name, name_len, Z_STRVAL_PP(val), Z_STRLEN_PP(val), replace, NULL);
-               if (orig != *val) {
-                       zval_ptr_dtor(val);
-               }
+               http_send_header_ex(name, name_len, Z_STRVAL_P(data), Z_STRLEN_P(data), replace, NULL);
+               zval_ptr_dtor(&data);
        }
 }
 /* }}} */
index bdfd2cf..09558a2 100644 (file)
@@ -445,9 +445,7 @@ PHP_HTTP_API STATUS _http_urlencode_hash_recursive(HashTable *ht, phpstr *str, c
                                return FAILURE;
                        }
                } else {
-                       zval val = zval_used_for_init;
-                       ZVAL_ZVAL(&val, *data, 1, 0);
-                       convert_to_string(&val);
+                       zval *val = http_zsep(IS_STRING, *data);
                        
                        if (PHPSTR_LEN(str)) {
                                phpstr_append(str, arg_sep, arg_sep_len);
@@ -455,16 +453,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(val) && Z_STRVAL(val)) {
+                       if (Z_STRLEN_P(val) && Z_STRVAL_P(val)) {
                                char *encoded_val;
                                int encoded_len;
                                
-                               encoded_val = php_url_encode(Z_STRVAL(val), Z_STRLEN(val), &encoded_len);
+                               encoded_val = php_url_encode(Z_STRVAL_P(val), Z_STRLEN_P(val), &encoded_len);
                                phpstr_append(str, encoded_val, encoded_len);
                                efree(encoded_val);
                        }
                        
-                       zval_dtor(&val);
+                       zval_ptr_dtor(&val);
                }
                phpstr_dtor(&new_prefix);
        }
index bb6035d..5ff7658 100644 (file)
@@ -31,7 +31,7 @@ support. Parallel requests are available for PHP 5 and greater.
  <date>2008-12-05</date>
  <version>
   <release>1.7.0-dev</release>
-  <api>1.6.0</api>
+  <api>1.7.0</api>
  </version>
  <stability>
   <release>stable</release>
@@ -39,6 +39,11 @@ support. Parallel requests are available for PHP 5 and greater.
  </stability>
  <license>BSD, revised</license>
  <notes><![CDATA[
+* Fixed bug #15495 (HttpMessage::setHttpVersion segfault)
+* Fixed bug #15497 (HttpInflateStream::finish segfault)
+* Fixed bug #15499 (HttpRequest::addHeaders segfault)
+* Fixed bug #15509 (HttpMessage::rewind memory leaks)
+* Fixed bug #15800 (Double free when zval is separated in convert_to_*)
 * Implement Request #14408 (Add a customizable timeout for HttpRequestPool::socketSelect)
 * Added request options:
  - postredir: enforcing RFC conformig POST after redirect (libcurl >= 7.17.1)
@@ -157,6 +162,7 @@ support. Parallel requests are available for PHP 5 and greater.
     <file role="test" name="log.inc"/>
     <file role="test" name="allowed_methods_002_logging.phpt"/>
     <file role="test" name="allowed_methods_002.phpt"/>
+    <file role="test" name="bug_15800.phpt"/>
     <file role="test" name="build_str_001.phpt"/>
     <file role="test" name="build_url_001.phpt"/>
     <file role="test" name="build_url_002.phpt"/>
index fa0c1c8..e74c18d 100644 (file)
@@ -27,6 +27,7 @@
 #define HTTP_PARAMS_ALLOW_FAILURE      0x02
 #define HTTP_PARAMS_RAISE_ERROR                0x04
 #define HTTP_PARAMS_DEFAULT    (HTTP_PARAMS_ALLOW_COMMA|HTTP_PARAMS_ALLOW_FAILURE|HTTP_PARAMS_RAISE_ERROR)
+#define HTTP_PARAMS_COLON_SEPARATOR    0x10
 
 extern PHP_MINIT_FUNCTION(http_support);
 
@@ -248,8 +249,8 @@ static inline const char *_http_locate_eol(const char *line, int *eol_len)
        return eol;
 }
 
-#define convert_to_type(t, z) _convert_to_type((t), (z))
-static inline zval *_convert_to_type(int type, zval *z)
+#define http_zset(t, z) _http_zset((t), (z))
+static inline zval *_http_zset(int type, zval *z)
 {
        if (Z_TYPE_P(z) != type) {
                switch (type) {
@@ -264,12 +265,10 @@ static inline zval *_convert_to_type(int type, zval *z)
        }
        return 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)
-{
-       if (p) {
-               *p = z;
-       }
+#define http_zsep(t, z) _http_zsep_ex((t), (z), NULL)
+#define http_zsep_ex(t, z, p) _http_zsep_ex((t), (z), (p))
+static inline zval *_http_zsep_ex(int type, zval *z, zval **p) {
+       SEPARATE_ARG_IF_REF(z);
        if (Z_TYPE_P(z) != type) {
                switch (type) {
                        case IS_NULL:   convert_to_null_ex(&z);         break;
@@ -282,11 +281,7 @@ static inline zval *_convert_to_type_ex(int type, zval *z, zval **p)
                }
        }
        if (p) {
-               if (*p == z) {
-                       *p = NULL;
-               } else {
-                       *p = z;
-               }
+               *p = z;
        }
        return z;
 }
index ed46b23..eb33bd5 100644 (file)
        }
 #define HTTP_CURL_OPT_STRING_EX(keyname, optname, obdc) \
        if (!strcasecmp(key.str, keyname)) { \
-               zval *copy_tmp, *copy = http_request_option_cache_ex(request, keyname, strlen(keyname)+1, 0, convert_to_type_ex(IS_STRING, *param, &copy_tmp)); \
+               zval *copy = http_request_option_cache_ex(request, keyname, strlen(keyname)+1, 0, http_zsep(IS_STRING, *param)); \
                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); \
-               } \
+               zval_ptr_dtor(&copy); \
                continue; \
        }
 #define HTTP_CURL_OPT_LONG(OPTION, ldiff) \
        }
 #define HTTP_CURL_OPT_LONG_EX(keyname, optname) \
        if (!strcasecmp(key.str, keyname)) { \
-               zval *copy = *param; \
-               convert_to_long_ex(&copy); \
+               zval *copy = http_zsep(IS_LONG, *param); \
                HTTP_CURL_OPT(optname, Z_LVAL_P(copy)); \
-               if (copy != *param) { \
-                       zval_ptr_dtor(&copy); \
-               } \
+               zval_ptr_dtor(&copy); \
                continue; \
        }
 
index 70c1aae..cc15461 100644 (file)
@@ -93,11 +93,10 @@ static inline php_url *_http_url_from_struct(php_url *url, HashTable *ht TSRMLS_
                if (Z_TYPE_PP(e) == IS_LONG) {
                        url->port = (unsigned short) Z_LVAL_PP(e);
                } else {
-                       zval *o = *e;
+                       zval *o = http_zsep(IS_LONG, *e);
                        
-                       convert_to_long_ex(e);
-                       url->port = (unsigned short) Z_LVAL_PP(e);
-                       if (o != *e) zval_ptr_dtor(e);
+                       url->port = (unsigned short) Z_LVAL_P(o);
+                       zval_ptr_dtor(&o);
                }
        }
        
index 88b7884..2c88b60 100644 (file)
@@ -4,7 +4,7 @@ HttpResponse - send cached gzipped data
 <?php 
 include 'skip.inc';
 checkcgi();
-checkmin("5.2.5");
+checkmin("5.2.7");
 skipif(!http_support(HTTP_SUPPORT_ENCODINGS), "need zlib support");
 ?>
 --ENV--
@@ -23,6 +23,5 @@ Status: 304%s
 X-Powered-By: PHP/%s
 Cache-Control: public, must-revalidate, max-age=3600
 Last-Modified: %s
-Content-Type: %s
 Accept-Ranges: bytes
 ETag: "900150983cd24fb0d6963f7d28e17f72"
diff --git a/tests/bug_15800.phpt b/tests/bug_15800.phpt
new file mode 100644 (file)
index 0000000..8282c84
--- /dev/null
@@ -0,0 +1,49 @@
+--TEST--
+Bug #15800 Double free when zval is separated in convert_to_*
+--SKIPIF--
+<?php
+include 'skip.inc';
+checkmin("5.2.5");
+checkcls('HttpRequest');
+skipif(!function_exists('debug_zval_dump'), "need DEBUG version of PHP");
+?>
+--FILE--
+<?php
+echo "-TEST\n";
+$o = array('ssl' => array('verifypeer'=>'1'));
+debug_zval_dump($o);
+
+$r = new HttpRequest('http://www.google.com');
+$r->setOptions($o);
+$r->send();
+debug_zval_dump($o);
+
+unset($r);
+debug_zval_dump($o);
+
+echo "Done\n";
+?>
+--EXPECTF--
+%aTEST
+array(1) refcount(2){
+  ["ssl"]=>
+  array(1) refcount(1){
+    ["verifypeer"]=>
+    string(1) "1" refcount(1)
+  }
+}
+array(1) refcount(2){
+  ["ssl"]=>
+  array(1) refcount(1){
+    ["verifypeer"]=>
+    string(1) "1" refcount(2)
+  }
+}
+array(1) refcount(2){
+  ["ssl"]=>
+  array(1) refcount(1){
+    ["verifypeer"]=>
+    string(1) "1" refcount(1)
+  }
+}
+Done