Skip to content

Commit

Permalink
Merge pull request #325 from joke2k/feature/cache-url-test
Browse files Browse the repository at this point in the history
Safely evaluate a string containing an invalid Python literal
  • Loading branch information
sergeyklay committed Sep 7, 2021
2 parents 192b813 + e928b6a commit 64209ed
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 3 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.rst
Expand Up @@ -17,12 +17,13 @@ Added
`#314 <https://github.com/joke2k/django-environ/pull/314>`_.
- Provided ability to use ``bytes`` or ``str`` as a default value for ``Env.bytes()``.


Fixed
+++++
- Fixed links in the documentation
- Fixed links in the documentation.
- Use default option in ``Env.bytes()``
`#206 <https://github.com/joke2k/django-environ/pull/206>`_.
- Safely evaluate a string containing an invalid Python literal
`#200 <https://github.com/joke2k/django-environ/issues/200>`_.

Changed
+++++++
Expand Down
2 changes: 1 addition & 1 deletion environ/environ.py
Expand Up @@ -44,7 +44,7 @@ def _cast(value):
# https://docs.python.org/3/library/ast.html#ast.literal_eval
try:
return ast.literal_eval(value)
except ValueError:
except (ValueError, SyntaxError):
return value


Expand Down
77 changes: 77 additions & 0 deletions tests/test_cache.py
Expand Up @@ -149,3 +149,80 @@ def test_unknown_backend():
def test_empty_url_is_mapped_to_empty_config():
assert Env.cache_url_config('') == {}
assert Env.cache_url_config(None) == {}


@pytest.mark.parametrize(
'chars',
['!', '$', '&', "'", '(', ')', '*', '+', ';', '=', '-', '.', '-v1.2']
)
def test_cache_url_password_using_sub_delims(monkeypatch, chars):
"""Ensure CACHE_URL passwords may contains some unsafe characters.
See: https://github.com/joke2k/django-environ/issues/200 for details."""
url = 'rediss://enigma:secret{}@ondigitalocean.com:25061/2'.format(chars)
monkeypatch.setenv('CACHE_URL', url)
env = Env()

result = env.cache()
assert result['BACKEND'] == 'django_redis.cache.RedisCache'
assert result['LOCATION'] == url

result = env.cache_url_config(url)
assert result['BACKEND'] == 'django_redis.cache.RedisCache'
assert result['LOCATION'] == url

url = 'rediss://enigma:sec{}ret@ondigitalocean.com:25061/2'.format(chars)
monkeypatch.setenv('CACHE_URL', url)
env = Env()

result = env.cache()
assert result['BACKEND'] == 'django_redis.cache.RedisCache'
assert result['LOCATION'] == url

result = env.cache_url_config(url)
assert result['BACKEND'] == 'django_redis.cache.RedisCache'
assert result['LOCATION'] == url

url = 'rediss://enigma:{}secret@ondigitalocean.com:25061/2'.format(chars)
monkeypatch.setenv('CACHE_URL', url)
env = Env()

result = env.cache()
assert result['BACKEND'] == 'django_redis.cache.RedisCache'
assert result['LOCATION'] == url

result = env.cache_url_config(url)
assert result['BACKEND'] == 'django_redis.cache.RedisCache'
assert result['LOCATION'] == url


@pytest.mark.parametrize(
'chars', ['%3A', '%2F', '%3F', '%23', '%5B', '%5D', '%40', '%2C']
)
def test_cache_url_password_using_gen_delims(monkeypatch, chars):
"""Ensure CACHE_URL passwords may contains %-encoded characters.
See: https://github.com/joke2k/django-environ/issues/200 for details."""
url = 'rediss://enigma:secret{}@ondigitalocean.com:25061/2'.format(chars)
monkeypatch.setenv('CACHE_URL', url)
env = Env()

result = env.cache()
assert result['BACKEND'] == 'django_redis.cache.RedisCache'
assert result['LOCATION'] == url

url = 'rediss://enigma:sec{}ret@ondigitalocean.com:25061/2'.format(chars)
monkeypatch.setenv('CACHE_URL', url)
env = Env()

result = env.cache()
assert result['BACKEND'] == 'django_redis.cache.RedisCache'
assert result['LOCATION'] == url

url = 'rediss://enigma:{}secret@ondigitalocean.com:25061/2'.format(chars)
monkeypatch.setenv('CACHE_URL', url)
env = Env()

result = env.cache()
assert result['BACKEND'] == 'django_redis.cache.RedisCache'
assert result['LOCATION'] == url
22 changes: 22 additions & 0 deletions tests/test_utils.py
@@ -0,0 +1,22 @@
# This file is part of the django-environ.
#
# Copyright (c) 2021, Serghei Iakovlev <egrep@protonmail.ch>
# Copyright (c) 2013-2021, Daniele Faraglia <daniele.faraglia@gmail.com>
#
# For the full copyright and license information, please view
# the LICENSE.txt file that was distributed with this source code.

import pytest
from environ.environ import _cast


@pytest.mark.parametrize(
'literal',
['anything-', 'anything*', '*anything', 'anything.',
'anything.1', '(anything', 'anything-v1.2', 'anything-1.2', 'anything=']
)
def test_cast(literal):
"""Safely evaluate a string containing an invalid Python literal.
See https://github.com/joke2k/django-environ/issues/200 for details."""
assert _cast(literal) == literal

0 comments on commit 64209ed

Please sign in to comment.