]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.2' into PHP-7.3
authorStanislav Malyshev <stas@php.net>
Sat, 2 Jan 2021 05:06:07 +0000 (21:06 -0800)
committerStanislav Malyshev <stas@php.net>
Sat, 2 Jan 2021 05:06:07 +0000 (21:06 -0800)
* PHP-7.2:
  Fix #77423: parse_url() will deliver a wrong host to user

1  2 
ext/standard/tests/url/parse_url_basic_001.phpt
ext/standard/tests/url/parse_url_basic_003.phpt
ext/standard/tests/url/parse_url_basic_005.phpt
ext/standard/tests/url/parse_url_unterminated.phpt
ext/standard/url.c

index 98dc0f786dc432e88eb5ade27a490f13af637d8e,8d155bb9846c97701dee5ac54c7e0bbcc6c84366..157d61466e698bf3a9e679ac3385a88d56eff1fa
@@@ -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;