From 9133039ec67b62a020f053dac98e99313715e242 Mon Sep 17 00:00:00 2001 From: Klaas van Schelven Date: Fri, 19 Aug 2022 09:46:13 +0200 Subject: [PATCH] Be more strict about url scheme parsing The error message implied that urls had to start with `scheme://`. However, if the double slash was left out, the url parsed just fine and the part that was ostensibly intended to be the hostname ended up as part of the path, whereas the default (localhost) would be used for the hostname. This commit makes the check as strict as the error message implies by including a check for the double slash. --- redis/connection.py | 17 +++++++++++------ tests/test_connection_pool.py | 8 ++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/redis/connection.py b/redis/connection.py index 3438bafe57..96645ba355 100755 --- a/redis/connection.py +++ b/redis/connection.py @@ -1166,6 +1166,16 @@ def to_bool(value): def parse_url(url): + if not ( + url.startswith("redis://") + or url.startswith("rediss://") + or url.startswith("unix://") + ): + raise ValueError( + "Redis URL must specify one of the following " + "schemes (redis://, rediss://, unix://)" + ) + url = urlparse(url) kwargs = {} @@ -1192,7 +1202,7 @@ def parse_url(url): kwargs["path"] = unquote(url.path) kwargs["connection_class"] = UnixDomainSocketConnection - elif url.scheme in ("redis", "rediss"): + else: # implied: url.scheme in ("redis", "rediss"): if url.hostname: kwargs["host"] = unquote(url.hostname) if url.port: @@ -1208,11 +1218,6 @@ def parse_url(url): if url.scheme == "rediss": kwargs["connection_class"] = SSLConnection - else: - raise ValueError( - "Redis URL must specify one of the following " - "schemes (redis://, rediss://, unix://)" - ) return kwargs diff --git a/tests/test_connection_pool.py b/tests/test_connection_pool.py index a836f5b2c7..636b04efad 100644 --- a/tests/test_connection_pool.py +++ b/tests/test_connection_pool.py @@ -339,6 +339,14 @@ def test_invalid_scheme_raises_error(self): "(redis://, rediss://, unix://)" ) + def test_invalid_scheme_raises_error_when_double_slash_missing(self): + with pytest.raises(ValueError) as cm: + redis.ConnectionPool.from_url("redis:foo.bar.com:12345") + assert str(cm.value) == ( + "Redis URL must specify one of the following schemes " + "(redis://, rediss://, unix://)" + ) + class TestConnectionPoolUnixSocketURLParsing: def test_defaults(self):