From 8f7a0af9515a6441b692719310c3e02832d9de65 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 18 Apr 2018 14:47:04 +0200 Subject: [PATCH 1/4] Allow IPv6 database hosts Signed-off-by: Joas Schilling --- lib/private/DB/ConnectionFactory.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/private/DB/ConnectionFactory.php b/lib/private/DB/ConnectionFactory.php index c841a36bb5..f5b8a9d3c2 100644 --- a/lib/private/DB/ConnectionFactory.php +++ b/lib/private/DB/ConnectionFactory.php @@ -193,13 +193,14 @@ class ConnectionFactory { $connectionParams['path'] = $dataDir . '/' . $name . '.db'; } else { $host = $this->config->getValue('dbhost', ''); - if (strpos($host, ':')) { - // Host variable may carry a port or socket. - list($host, $portOrSocket) = explode(':', $host, 2); - if (ctype_digit($portOrSocket)) { - $connectionParams['port'] = $portOrSocket; + $matches = []; + if (preg_match('/^(.*):([^\]:]+)$/', $host, $matches)) { + // Host variable carries a port or socket. + $host = $matches[1]; + if (is_numeric($matches[2])) { + $connectionParams['port'] = (int) $matches[2]; } else { - $connectionParams['unix_socket'] = $portOrSocket; + $connectionParams['unix_socket'] = $matches[2]; } } $connectionParams['host'] = $host; From 78ee3abb786eea385b3149279ba6d8903d8a7b1a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 19 Apr 2018 12:49:36 +0200 Subject: [PATCH 2/4] Move regex to a function and add tests Signed-off-by: Joas Schilling --- lib/private/DB/ConnectionFactory.php | 35 +++++++++++------ tests/lib/DB/ConnectionFactoryTest.php | 52 ++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 tests/lib/DB/ConnectionFactoryTest.php diff --git a/lib/private/DB/ConnectionFactory.php b/lib/private/DB/ConnectionFactory.php index f5b8a9d3c2..9fc2ed42c3 100644 --- a/lib/private/DB/ConnectionFactory.php +++ b/lib/private/DB/ConnectionFactory.php @@ -193,17 +193,7 @@ class ConnectionFactory { $connectionParams['path'] = $dataDir . '/' . $name . '.db'; } else { $host = $this->config->getValue('dbhost', ''); - $matches = []; - if (preg_match('/^(.*):([^\]:]+)$/', $host, $matches)) { - // Host variable carries a port or socket. - $host = $matches[1]; - if (is_numeric($matches[2])) { - $connectionParams['port'] = (int) $matches[2]; - } else { - $connectionParams['unix_socket'] = $matches[2]; - } - } - $connectionParams['host'] = $host; + $connectionParams = array_merge($connectionParams, $this->splitHostFromPortAndSocket($host)); $connectionParams['dbname'] = $name; } @@ -233,4 +223,27 @@ class ConnectionFactory { return $connectionParams; } + + /** + * @param string $host + * @return array + */ + protected function splitHostFromPortAndSocket($host): array { + $params = [ + 'host' => $host, + ]; + + $matches = []; + if (preg_match('/^(.*):([^\]:]+)$/', $host, $matches)) { + // Host variable carries a port or socket. + $params['host'] = $matches[1]; + if (is_numeric($matches[2])) { + $params['port'] = (int) $matches[2]; + } else { + $params['unix_socket'] = $matches[2]; + } + } + + return $params; + } } diff --git a/tests/lib/DB/ConnectionFactoryTest.php b/tests/lib/DB/ConnectionFactoryTest.php new file mode 100644 index 0000000000..6b8545ab07 --- /dev/null +++ b/tests/lib/DB/ConnectionFactoryTest.php @@ -0,0 +1,52 @@ + + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace Test\DB; + +use OC\DB\ConnectionFactory; +use OC\SystemConfig; +use Test\TestCase; + +class ConnectionFactoryTest extends TestCase { + + public function splitHostFromPortAndSocketData() { + return [ + ['127.0.0.1', ['host' => '127.0.0.1']], + ['[::1]', ['host' => '[::1]']], + ['127.0.0.1:3306', ['host' => '127.0.0.1', 'port' => 3306]], + ['[::1]:3306', ['host' => '[::1]', 'port' => 3306]], + ['unix:/socket', ['host' => 'unix', 'unix_socket' => '/socket']], + ]; + } + + /** + * @dataProvider splitHostFromPortAndSocketData + * @param string $host + * @param array $expected + */ + public function testSplitHostFromPortAndSocket($host, array $expected) { + /** @var SystemConfig $config */ + $config = $this->createMock(SystemConfig::class); + $factory = new ConnectionFactory($config); + + $this->assertEquals($expected, self::invokePrivate($factory, 'splitHostFromPortAndSocket', [$host])); + } +} From d686b19a16a45367bbe30665f78acd475d226d5c Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Thu, 19 Apr 2018 13:58:02 +0200 Subject: [PATCH 3/4] Add tests for domains Signed-off-by: Morris Jobke --- tests/lib/DB/ConnectionFactoryTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/lib/DB/ConnectionFactoryTest.php b/tests/lib/DB/ConnectionFactoryTest.php index 6b8545ab07..062a55b5d6 100644 --- a/tests/lib/DB/ConnectionFactoryTest.php +++ b/tests/lib/DB/ConnectionFactoryTest.php @@ -30,8 +30,10 @@ class ConnectionFactoryTest extends TestCase { public function splitHostFromPortAndSocketData() { return [ ['127.0.0.1', ['host' => '127.0.0.1']], + ['db.example.org', ['host' => 'db.example.org']], ['[::1]', ['host' => '[::1]']], ['127.0.0.1:3306', ['host' => '127.0.0.1', 'port' => 3306]], + ['db.example.org:3306', ['host' => 'db.example.org', 'port' => 3306]], ['[::1]:3306', ['host' => '[::1]', 'port' => 3306]], ['unix:/socket', ['host' => 'unix', 'unix_socket' => '/socket']], ]; From a4cb83df272a3c98a439d2e999095034f730acc5 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Thu, 19 Apr 2018 13:59:08 +0200 Subject: [PATCH 4/4] Add tests for special domain name Signed-off-by: Morris Jobke --- tests/lib/DB/ConnectionFactoryTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/lib/DB/ConnectionFactoryTest.php b/tests/lib/DB/ConnectionFactoryTest.php index 062a55b5d6..6a1a9b31c4 100644 --- a/tests/lib/DB/ConnectionFactoryTest.php +++ b/tests/lib/DB/ConnectionFactoryTest.php @@ -31,9 +31,11 @@ class ConnectionFactoryTest extends TestCase { return [ ['127.0.0.1', ['host' => '127.0.0.1']], ['db.example.org', ['host' => 'db.example.org']], + ['unix', ['host' => 'unix']], ['[::1]', ['host' => '[::1]']], ['127.0.0.1:3306', ['host' => '127.0.0.1', 'port' => 3306]], ['db.example.org:3306', ['host' => 'db.example.org', 'port' => 3306]], + ['unix:3306', ['host' => 'unix', 'port' => 3306]], ['[::1]:3306', ['host' => '[::1]', 'port' => 3306]], ['unix:/socket', ['host' => 'unix', 'unix_socket' => '/socket']], ];