diff options
Diffstat (limited to 'ext/standard/url.c')
-rw-r--r-- | ext/standard/url.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/ext/standard/url.c b/ext/standard/url.c index 98dc0f786d..157d61466e 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -102,6 +102,24 @@ static const char *binary_strcspn(const char *s, const char *e, const char *char return e; } +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) { zend_bool has_port; @@ -242,13 +260,17 @@ parse_host: ret->pass = zend_string_init(pp, (p-pp), 0); php_replace_controlchars_ex(ZSTR_VAL(ret->pass), ZSTR_LEN(ret->pass)); } else { - ret->user = zend_string_init(s, (p-s), 0); + if (!is_userinfo_valid(s, p-s)) { + goto check_port; + } + ret->user = zend_string_init(s, (p-s), 0); php_replace_controlchars_ex(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user)); } s = p + 1; } +check_port: /* check for port */ if (s < ue && *s == '[' && *(e-1) == ']') { /* Short circuit portscan, |