summaryrefslogtreecommitdiff
path: root/ext/standard/url.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/url.c')
-rw-r--r--ext/standard/url.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/ext/standard/url.c b/ext/standard/url.c
index 78ca472a2b..a33ff9ae82 100644
--- a/ext/standard/url.c
+++ b/ext/standard/url.c
@@ -242,6 +242,21 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
/* check for login and password */
if ((p = zend_memrchr(s, '@', (e-s)))) {
+ /* check for invalid chars inside login/pass */
+ pp = s;
+ while (pp < p) {
+ /* http://www.rfc-editor.org/rfc/rfc3986.txt ยง3.2.1 */
+ const char search_rfc3986[] = ":;=!$%_-.~&'()*+,";
+ if (!isalnum(*pp) && !strchr(search_rfc3986, *pp)) {
+ if (ret->scheme) {
+ efree(ret->scheme);
+ }
+ efree(ret);
+ return NULL;
+ }
+ pp++;
+ }
+
if ((pp = memchr(s, ':', (p-s)))) {
ret->user = estrndup(s, (pp-s));
php_replace_controlchars_ex(ret->user, (pp - s));
@@ -708,22 +723,24 @@ PHPAPI size_t php_raw_url_decode(char *str, size_t len)
}
/* }}} */
-/* {{{ proto array get_headers(string url[, int format])
+/* {{{ proto array get_headers(string url[, int format[, resource context]])
fetches all the headers sent by the server in response to a HTTP request */
PHP_FUNCTION(get_headers)
{
char *url;
size_t url_len;
- php_stream_context *context;
php_stream *stream;
zval *prev_val, *hdr = NULL, *h;
HashTable *hashT;
zend_long format = 0;
+ zval *zcontext = NULL;
+ php_stream_context *context;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &url, &url_len, &format) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lr!", &url, &url_len, &format, &zcontext) == FAILURE) {
return;
}
- context = FG(default_context) ? FG(default_context) : (FG(default_context) = php_stream_context_alloc());
+
+ context = php_stream_context_from_zval(zcontext, 0);
if (!(stream = php_stream_open_wrapper_ex(url, "r", REPORT_ERRORS | STREAM_USE_URL | STREAM_ONLY_GET_HEADERS, NULL, context))) {
RETURN_FALSE;