From: Stanislav Malyshev Date: Sat, 2 Jan 2021 05:06:07 +0000 (-0800) Subject: Merge branch 'PHP-7.2' into PHP-7.3 X-Git-Tag: php-7.3.27~8 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=128fca40376140c60b47a1c3750bb6435866838e;p=php Merge branch 'PHP-7.2' into PHP-7.3 * PHP-7.2: Fix #77423: parse_url() will deliver a wrong host to user --- 128fca40376140c60b47a1c3750bb6435866838e diff --cc ext/standard/url.c index 98dc0f786d,8d155bb984..157d61466e --- a/ext/standard/url.c +++ b/ext/standard/url.c @@@ -91,26 -92,25 +91,44 @@@ PHPAPI php_url *php_url_parse(char cons return php_url_parse_ex(str, strlen(str)); } +static const char *binary_strcspn(const char *s, const char *e, const char *chars) { + while (*chars) { + const char *p = memchr(s, *chars, e - s); + if (p) { + e = p; + } + chars++; + } + 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; + return php_url_parse_ex2(str, length, &has_port); +} + +/* {{{ php_url_parse_ex2 + */ +PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, zend_bool *has_port) { char port_buf[6]; php_url *ret = ecalloc(1, sizeof(php_url)); @@@ -235,15 -244,19 +253,18 @@@ parse_host /* check for login and password */ if ((p = zend_memrchr(s, '@', (e-s)))) { if ((pp = memchr(s, ':', (p-s)))) { - ret->user = estrndup(s, (pp-s)); - php_replace_controlchars_ex(ret->user, (pp - s)); + ret->user = zend_string_init(s, (pp-s), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user)); pp++; - ret->pass = estrndup(pp, (p-pp)); - php_replace_controlchars_ex(ret->pass, (p-pp)); + 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 = estrndup(s, (p-s)); - php_replace_controlchars_ex(ret->user, (p-s)); - ++ 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;