From: Michael Wallner Date: Fri, 25 Sep 2015 12:37:15 +0000 (+0200) Subject: Merge R_2_5 X-Git-Tag: RELEASE_3_0_0_RC1~21 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=4bf1b4570329514fa00dc68c6e02f581c3792d73;p=m6w6%2Fext-http Merge R_2_5 --- 4bf1b4570329514fa00dc68c6e02f581c3792d73 diff --cc php_http_info.c index f389be9,4fb067f..6eef822 --- a/php_http_info.c +++ b/php_http_info.c @@@ -135,10 -135,14 +135,14 @@@ php_http_info_t *php_http_info_parse(ph if (http > url) { /* CONNECT presents an authority only */ if (strcasecmp(PHP_HTTP_INFO(info).request.method, "CONNECT")) { - PHP_HTTP_INFO(info).request.url = php_http_url_parse(url, http - url, ~0 TSRMLS_CC); + PHP_HTTP_INFO(info).request.url = php_http_url_parse(url, http - url, ~0); } else { - PHP_HTTP_INFO(info).request.url = php_http_url_parse_authority(url, http - url, ~0 TSRMLS_CC); + PHP_HTTP_INFO(info).request.url = php_http_url_parse_authority(url, http - url, ~0); } + if (!PHP_HTTP_INFO(info).request.url) { + PTR_SET(PHP_HTTP_INFO(info).request.method, NULL); + return NULL; + } } else { PTR_SET(PHP_HTTP_INFO(info).request.method, NULL); return NULL; diff --cc php_http_message.c index f06065a,c6b03ff..e6cdbc8 --- a/php_http_message.c +++ b/php_http_message.c @@@ -1571,14 -1615,14 +1571,14 @@@ static PHP_METHOD(HttpMessage, setReque return; } - zend_replace_error_handling(EH_THROW, php_http_exception_bad_url_class_entry, &zeh TSRMLS_CC); - url = php_http_url_from_zval(zurl, ~0 TSRMLS_CC); - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, php_http_exception_bad_url_class_entry, &zeh); + url = php_http_url_from_zval(zurl, ~0); + zend_restore_error_handling(&zeh); - if (php_http_url_is_empty(url)) { + if (url && php_http_url_is_empty(url)) { php_http_url_free(&url); php_http_throw(invalid_arg, "Cannot set http\\Message's request url to an empty string", NULL); - } else { + } else if (url) { PTR_SET(obj->message->http.info.request.url, url); } diff --cc php_http_url.c index afe39bf,81b2d95..c5c19a5 --- a/php_http_url.c +++ b/php_http_url.c @@@ -1026,44 -1020,56 +1026,55 @@@ static ZEND_RESULT_CODE parse_widn(stru } #endif - static ZEND_RESULT_CODE parse_hostinfo(struct parse_state *state, const char *ptr) + #ifdef HAVE_INET_PTON + static const char *parse_ip6(struct parse_state *state, const char *ptr) { + size_t mb, len; - const char *end = state->ptr, *tmp = ptr, *port = NULL; - - #ifdef HAVE_INET_PTON - if (*ptr == '[') { - char *error = NULL, *tmp = memchr(ptr, ']', end - ptr); - - if (tmp) { - size_t addrlen = tmp - ptr + 1; - char buf[16], *addr = estrndup(ptr + 1, addrlen - 2); - int rv = inet_pton(AF_INET6, addr, buf); - - efree(addr); - if (rv == 1) { - state->buffer[state->offset] = '['; - state->url.host = &state->buffer[state->offset]; - inet_ntop(AF_INET6, buf, state->url.host + 1, state->maxlen - state->offset); - state->offset += strlen(state->url.host); - state->buffer[state->offset++] = ']'; - state->buffer[state->offset++] = 0; - ptr = tmp + 1; - } else if (rv == -1) { - error = strerror(errno); - } else { - error = "unexpected '['"; - } + const char *error = NULL, *end = state->ptr, *tmp = memchr(ptr, ']', end - ptr); - TSRMLS_FETCH_FROM_CTX(state->ts); + + if (tmp) { + size_t addrlen = tmp - ptr + 1; + char buf[16], *addr = estrndup(ptr + 1, addrlen - 2); + int rv = inet_pton(AF_INET6, addr, buf); + + if (rv == 1) { + state->buffer[state->offset] = '['; + state->url.host = &state->buffer[state->offset]; + inet_ntop(AF_INET6, buf, state->url.host + 1, state->maxlen - state->offset); + state->offset += strlen(state->url.host); + state->buffer[state->offset++] = ']'; + state->buffer[state->offset++] = 0; + ptr = tmp + 1; + } else if (rv == -1) { + error = strerror(errno); } else { - error = "expected ']'"; + error = "unexpected '['"; } + efree(addr); + } else { + error = "expected ']'"; + } - if (error) { - php_error_docref(NULL, E_WARNING, "Failed to parse hostinfo; %s", error); - return FAILURE; - } + if (error) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse hostinfo; %s", error); ++ php_error_docref(NULL, E_WARNING, "Failed to parse hostinfo; %s", error); + return NULL; + } + + return ptr; + } + #endif + + static ZEND_RESULT_CODE parse_hostinfo(struct parse_state *state, const char *ptr) + { + size_t mb, len; + const char *end = state->ptr, *tmp = ptr, *port = NULL, *label = NULL; - TSRMLS_FETCH_FROM_CTX(state->ts); + + #ifdef HAVE_INET_PTON + if (*ptr == '[' && !(ptr = parse_ip6(state, ptr))) { + return FAILURE; } #endif + if (ptr != end) do { switch (*ptr) { case ':': @@@ -1091,6 -1097,20 +1102,20 @@@ case '!': case '$': case '&': case '\'': case '(': case ')': case '*': case '+': case ',': case ';': case '=': /* sub-delims */ case '-': case '.': case '_': case '~': /* unreserved */ + if (port || !label) { + /* sort of a compromise, just ensure we don't end up + * with a dot at the beginning or two consecutive dots + */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, ++ php_error_docref(NULL, E_WARNING, + "Failed to parse %s; unexpected '%c' at pos %u in '%s'", + port ? "port" : "host", + (unsigned char) *ptr, (unsigned) (ptr - tmp), tmp); + return FAILURE; + } + state->buffer[state->offset++] = *ptr; + label = NULL; + break; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':