Index: src/parser/PhutilURI.php =================================================================== --- src/parser/PhutilURI.php +++ src/parser/PhutilURI.php @@ -35,8 +35,8 @@ // stringyness is to preserve API compatibility and // allow the tests to continue passing $this->protocol = idx($parts, 'scheme', ''); - $this->user = idx($parts, 'user', ''); - $this->pass = idx($parts, 'pass', ''); + $this->user = rawurldecode(idx($parts, 'user', '')); + $this->pass = rawurldecode(idx($parts, 'pass', '')); $this->domain = idx($parts, 'host', ''); $this->port = (string)idx($parts, 'port', ''); $this->path = idx($parts, 'path', ''); @@ -54,10 +54,11 @@ $protocol = nonempty($this->protocol, 'http'); $auth = ''; - if ($this->user && $this->pass) { - $auth = $this->user.':'.$this->pass.'@'; - } else if ($this->user) { - $auth = $this->user.'@'; + if (strlen($this->user) && strlen($this->pass)) { + $auth = phutil_escape_uri($this->user).':'. + phutil_escape_uri($this->pass).'@'; + } else if (strlen($this->user)) { + $auth = phutil_escape_uri($this->user).'@'; } $prefix = $protocol.'://'.$auth.$this->domain; Index: src/parser/__tests__/PhutilURITestCase.php =================================================================== --- src/parser/__tests__/PhutilURITestCase.php +++ src/parser/__tests__/PhutilURITestCase.php @@ -43,6 +43,26 @@ 'ssh://git@example.com/example/example.git', (string)$uri, 'uri'); + + + $uri = new PhutilURI('http://0@domain.com/'); + $this->assertEqual('0', $uri->getUser()); + $this->assertEqual('http://0@domain.com/', (string)$uri); + + $uri = new PhutilURI('http://0:0@domain.com/'); + $this->assertEqual('0', $uri->getUser()); + $this->assertEqual('0', $uri->getPass()); + $this->assertEqual('http://0:0@domain.com/', (string)$uri); + + $uri = new PhutilURI('http://%20:%20@domain.com/'); + $this->assertEqual(' ', $uri->getUser()); + $this->assertEqual(' ', $uri->getPass()); + $this->assertEqual('http://%20:%20@domain.com/', (string)$uri); + + $uri = new PhutilURI('http://%40:%40@domain.com/'); + $this->assertEqual('@', $uri->getUser()); + $this->assertEqual('@', $uri->getPass()); + $this->assertEqual('http://%40:%40@domain.com/', (string)$uri); } public function testURIGeneration() {