From b960634088df7cbeb47eab686b8b412c634876e3 Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Mon, 31 Jul 2023 09:33:23 -0700 Subject: [PATCH] Update DSN to support special chars for user and password Previously, DSN would not be able to parse special characters like "@" or "/". This adds support by requiring the input to be url encoded and then DSN would decode it after parsing. --- src/Appwrite/DSN/DSN.php | 6 +++--- tests/unit/DSN/DSNTest.php | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/Appwrite/DSN/DSN.php b/src/Appwrite/DSN/DSN.php index 5605640989..de6f0df9e0 100644 --- a/src/Appwrite/DSN/DSN.php +++ b/src/Appwrite/DSN/DSN.php @@ -55,8 +55,8 @@ class DSN } $this->scheme = $parts['scheme'] ?? null; - $this->user = $parts['user'] ?? null; - $this->password = $parts['pass'] ?? null; + $this->user = isset($parts['user']) ? \urldecode($parts['user']) : null; + $this->password = isset($parts['pass']) ? \urldecode($parts['pass']) : null; $this->host = $parts['host'] ?? null; $this->port = $parts['port'] ?? null; $this->database = $parts['path'] ?? null; @@ -124,7 +124,7 @@ class DSN } /** - * Return the query string + * Return the raw query string * * @return ?string */ diff --git a/tests/unit/DSN/DSNTest.php b/tests/unit/DSN/DSNTest.php index d1f5ba1197..4ff4fb9bf0 100644 --- a/tests/unit/DSN/DSNTest.php +++ b/tests/unit/DSN/DSNTest.php @@ -71,6 +71,39 @@ class DSNTest extends TestCase $this->assertNull($dsn->getPort()); $this->assertEmpty($dsn->getDatabase()); $this->assertNull($dsn->getQuery()); + + $password = 'sl/sh+$@no:her'; + $encoded = \urlencode($password); + $dsn = new DSN("sms://user:$encoded@localhost"); + $this->assertEquals("sms", $dsn->getScheme()); + $this->assertEquals("user", $dsn->getUser()); + $this->assertEquals($password, $dsn->getPassword()); + $this->assertEquals("localhost", $dsn->getHost()); + $this->assertNull($dsn->getPort()); + $this->assertEmpty($dsn->getDatabase()); + $this->assertNull($dsn->getQuery()); + + $user = 'admin@example.com'; + $encoded = \urlencode($user); + $dsn = new DSN("sms://$encoded@localhost"); + $this->assertEquals("sms", $dsn->getScheme()); + $this->assertEquals($user, $dsn->getUser()); + $this->assertNull($dsn->getPassword()); + $this->assertEquals("localhost", $dsn->getHost()); + $this->assertNull($dsn->getPort()); + $this->assertEmpty($dsn->getDatabase()); + $this->assertNull($dsn->getQuery()); + + $value = 'I am 100% value=, "right"?!'; + $encoded = \urlencode($value); + $dsn = new DSN("sms://localhost?value=$encoded"); + $this->assertEquals("sms", $dsn->getScheme()); + $this->assertNull($dsn->getUser()); + $this->assertNull($dsn->getPassword()); + $this->assertEquals("localhost", $dsn->getHost()); + $this->assertNull($dsn->getPort()); + $this->assertEmpty($dsn->getDatabase()); + $this->assertEquals("value=$encoded", $dsn->getQuery()); } public function testFail(): void