From 5ba379899fb1e05ede73674dc010ce8846e051c2 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 12 Feb 2009 13:11:05 +0000 Subject: [PATCH] Fixed bug #15800 --- ThanksTo.txt | 2 + http.c | 8 +- http_api.c | 39 ++++++--- http_cookie_api.c | 16 ++-- http_filter_api.c | 7 +- http_functions.c | 16 ++-- http_headers_api.c | 7 +- http_message_object.c | 22 +++-- http_querystring_api.c | 8 +- http_querystring_object.c | 7 +- http_request_api.c | 107 +++++++++++++----------- http_request_body_api.c | 53 ++++++------ http_request_object.c | 31 +++---- http_response_object.c | 159 +++++++++++------------------------- http_send_api.c | 22 ++--- http_url_api.c | 10 +-- package2.xml | 8 +- php_http_api.h | 21 ++--- php_http_request_int.h | 13 +-- php_http_url_api.h | 7 +- tests/HttpResponse_004.phpt | 3 +- tests/bug_15800.phpt | 49 +++++++++++ 22 files changed, 299 insertions(+), 316 deletions(-) create mode 100644 tests/bug_15800.phpt diff --git a/ThanksTo.txt b/ThanksTo.txt index f5f1da7..e736e4c 100644 --- a/ThanksTo.txt +++ b/ThanksTo.txt @@ -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 --- 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"); } diff --git a/http_api.c b/http_api.c index b54da54..4fa8c3d 100644 --- a/http_api.c +++ b/http_api.c @@ -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 { diff --git a/http_cookie_api.c b/http_cookie_api.c index 2f0d6c5..a9dd14c 100644 --- a/http_cookie_api.c +++ b/http_cookie_api.c @@ -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; diff --git a/http_filter_api.c b/http_filter_api.c index d072787..a78bb7b 100644 --- a/http_filter_api.c +++ b/http_filter_api.c @@ -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); } } } diff --git a/http_functions.c b/http_functions.c index 7b58cf7..94b62bf 100644 --- a/http_functions.c +++ b/http_functions.c @@ -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); } } diff --git a/http_headers_api.c b/http_headers_api.c index 1da83ae..4c0d2f4 100644 --- a/http_headers_api.c +++ b/http_headers_api.c @@ -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); diff --git a/http_message_object.c b/http_message_object.c index 8845681..6d271ba 100644 --- a/http_message_object.c +++ b/http_message_object.c @@ -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); } } diff --git a/http_querystring_api.c b/http_querystring_api.c index 5d636a3..4fc3986 100644 --- a/http_querystring_api.c +++ b/http_querystring_api.c @@ -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(¶ms); - sapi_module.treat_data(PARSE_STRING, estrdup(Z_STRVAL_P(params)), &array TSRMLS_CC); - zval_ptr_dtor(¶ms); + 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; diff --git a/http_querystring_object.c b/http_querystring_object.c index 9c183f3..f47eecf 100644 --- a/http_querystring_object.c +++ b/http_querystring_object.c @@ -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))) { diff --git a/http_request_api.c b/http_request_api.c index 42ef30f..4ebbc2f 100644 --- a/http_request_api.c +++ b/http_request_api.c @@ -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(©); - 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 */ /* diff --git a/http_request_body_api.c b/http_request_body_api.c index f2d5f56..bb969e6 100644 --- a/http_request_body_api.c +++ b/http_request_body_api.c @@ -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)); diff --git a/http_request_object.c b/http_request_object.c index c72d908..1795e37 100644 --- a/http_request_object.c +++ b/http_request_object.c @@ -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); } } } diff --git a/http_response_object.c b/http_response_object.c index ed634af..e638353 100644 --- a/http_response_object.c +++ b/http_response_object.c @@ -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; } } diff --git a/http_send_api.c b/http_send_api.c index ef8bf2d..4f97dac 100644 --- a/http_send_api.c +++ b/http_send_api.c @@ -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); } } /* }}} */ diff --git a/http_url_api.c b/http_url_api.c index bdfd2cf..09558a2 100644 --- a/http_url_api.c +++ b/http_url_api.c @@ -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); } diff --git a/package2.xml b/package2.xml index bb6035d..5ff7658 100644 --- a/package2.xml +++ b/package2.xml @@ -31,7 +31,7 @@ support. Parallel requests are available for PHP 5 and greater. 2008-12-05 1.7.0-dev - 1.6.0 + 1.7.0 stable @@ -39,6 +39,11 @@ support. Parallel requests are available for PHP 5 and greater. BSD, revised = 7.17.1) @@ -157,6 +162,7 @@ support. Parallel requests are available for PHP 5 and greater. + diff --git a/php_http_api.h b/php_http_api.h index fa0c1c8..e74c18d 100644 --- a/php_http_api.h +++ b/php_http_api.h @@ -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; } diff --git a/php_http_request_int.h b/php_http_request_int.h index ed46b23..eb33bd5 100644 --- a/php_http_request_int.h +++ b/php_http_request_int.h @@ -41,14 +41,12 @@ } #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, ©_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(©_tmp); \ - } \ + zval_ptr_dtor(©); \ continue; \ } #define HTTP_CURL_OPT_LONG(OPTION, ldiff) \ @@ -58,12 +56,9 @@ } #define HTTP_CURL_OPT_LONG_EX(keyname, optname) \ if (!strcasecmp(key.str, keyname)) { \ - zval *copy = *param; \ - convert_to_long_ex(©); \ + zval *copy = http_zsep(IS_LONG, *param); \ HTTP_CURL_OPT(optname, Z_LVAL_P(copy)); \ - if (copy != *param) { \ - zval_ptr_dtor(©); \ - } \ + zval_ptr_dtor(©); \ continue; \ } diff --git a/php_http_url_api.h b/php_http_url_api.h index 70c1aae..cc15461 100644 --- a/php_http_url_api.h +++ b/php_http_url_api.h @@ -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); } } diff --git a/tests/HttpResponse_004.phpt b/tests/HttpResponse_004.phpt index 88b7884..2c88b60 100644 --- a/tests/HttpResponse_004.phpt +++ b/tests/HttpResponse_004.phpt @@ -4,7 +4,7 @@ HttpResponse - send cached gzipped data --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 index 0000000..8282c84 --- /dev/null +++ b/tests/bug_15800.phpt @@ -0,0 +1,49 @@ +--TEST-- +Bug #15800 Double free when zval is separated in convert_to_* +--SKIPIF-- + +--FILE-- + 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 -- 2.30.2