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.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/ext/standard/url.c b/ext/standard/url.c
index 1dd073e2bb..8d155bb984 100644
--- a/ext/standard/url.c
+++ b/ext/standard/url.c
@@ -92,6 +92,22 @@ PHPAPI php_url *php_url_parse(char const *str)
return php_url_parse_ex(str, strlen(str));
}
+static int is_userinfo_valid(const char *str, size_t len)
+{
+ char *valid = "-._~!$&'()*+,;=:";
+ char *p = str;
+ while (p - str < len) {
+ if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) {
+ p++;
+ } else if (*p == '%' && p - str <= len - 3 && isdigit(*(p+1)) && isxdigit(*(p+2))) {
+ p += 3;
+ } else {
+ return 0;
+ }
+ }
+ return 1;
+}
+
/* {{{ php_url_parse
*/
PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
@@ -235,13 +251,18 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
ret->pass = estrndup(pp, (p-pp));
php_replace_controlchars_ex(ret->pass, (p-pp));
} else {
+ if (!is_userinfo_valid(s, p-s)) {
+ goto check_port;
+ }
ret->user = estrndup(s, (p-s));
php_replace_controlchars_ex(ret->user, (p-s));
+
}
s = p + 1;
}
+check_port:
/* check for port */
if (s < ue && *s == '[' && *(e-1) == ']') {
/* Short circuit portscan,