diff --git a/src/Factory.php b/src/Factory.php index 058f2c1..a75b88f 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -170,9 +170,9 @@ public function createConnection($uri) $connection = new Connection($stream, $executor); $command = $executor->enqueue(new AuthenticateCommand( - isset($parts['user']) ? $parts['user'] : 'root', - isset($parts['pass']) ? $parts['pass'] : '', - isset($parts['path']) ? ltrim($parts['path'], '/') : '' + isset($parts['user']) ? rawurldecode($parts['user']) : 'root', + isset($parts['pass']) ? rawurldecode($parts['pass']) : '', + isset($parts['path']) ? rawurldecode(ltrim($parts['path'], '/')) : '' )); $parser->start(); diff --git a/tests/FactoryTest.php b/tests/FactoryTest.php index 586903a..19508da 100644 --- a/tests/FactoryTest.php +++ b/tests/FactoryTest.php @@ -31,6 +31,40 @@ public function testConnectWillUseGivenHostAndGivenPort() $factory->createConnection('127.0.0.1:1234'); } + public function testConnectWillUseGivenUserInfoAsDatabaseCredentialsAfterUrldecoding() + { + $connection = $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->setMethods(array('write'))->getMock(); + $connection->expects($this->once())->method('write')->with($this->stringContains("user!\0")); + + $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector->expects($this->once())->method('connect')->with('127.0.0.1:3306')->willReturn(\React\Promise\resolve($connection)); + + $factory = new Factory($loop, $connector); + $promise = $factory->createConnection('user%21@127.0.0.1'); + + $promise->then($this->expectCallableNever(), $this->expectCallableNever()); + + $connection->emit('data', array("\x33\0\0\0" . "\x0a" . "mysql\0" . str_repeat("\0", 44))); + } + + public function testConnectWillUseGivenPathAsDatabaseNameAfterUrldecoding() + { + $connection = $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->setMethods(array('write'))->getMock(); + $connection->expects($this->once())->method('write')->with($this->stringContains("test database\0")); + + $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock(); + $connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock(); + $connector->expects($this->once())->method('connect')->with('127.0.0.1:3306')->willReturn(\React\Promise\resolve($connection)); + + $factory = new Factory($loop, $connector); + $promise = $factory->createConnection('127.0.0.1/test%20database'); + + $promise->then($this->expectCallableNever(), $this->expectCallableNever()); + + $connection->emit('data', array("\x33\0\0\0" . "\x0a" . "mysql\0" . str_repeat("\0", 44))); + } + public function testConnectWithInvalidUriWillRejectWithoutConnecting() { $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();