reject environment variable that contains white spaces

Signed-off-by: Hiroshi Ioka <hirochachacha@gmail.com>
This commit is contained in:
Hiroshi Ioka 2018-12-07 17:12:40 +09:00
parent 0fc3b51b50
commit afc161a0b1
3 changed files with 36 additions and 7 deletions

View File

@ -5,22 +5,33 @@ import codecs
import contextlib
import logging
import os
import string
import six
from ..const import IS_WINDOWS_PLATFORM
from .errors import ConfigurationError
from .errors import EnvFileNotFound
log = logging.getLogger(__name__)
whitespace = set(string.whitespace)
def split_env(env):
if isinstance(env, six.binary_type):
env = env.decode('utf-8', 'replace')
key = value = None
if '=' in env:
return env.split('=', 1)
key, value = env.split('=', 1)
else:
return env, None
key = env
for k in key:
if k in whitespace:
raise ConfigurationError(
"environment variable name '%s' may not contains white spaces." % key
)
return key, value
def env_vars_from_file(filename):
@ -28,16 +39,19 @@ def env_vars_from_file(filename):
Read in a line delimited file of environment variables.
"""
if not os.path.exists(filename):
raise ConfigurationError("Couldn't find env file: %s" % filename)
raise EnvFileNotFound("Couldn't find env file: %s" % filename)
elif not os.path.isfile(filename):
raise ConfigurationError("%s is not a file." % (filename))
raise EnvFileNotFound("%s is not a file." % (filename))
env = {}
with contextlib.closing(codecs.open(filename, 'r', 'utf-8-sig')) as fileobj:
for line in fileobj:
line = line.strip()
if line and not line.startswith('#'):
k, v = split_env(line)
env[k] = v
try:
k, v = split_env(line)
env[k] = v
except ConfigurationError as e:
raise ConfigurationError('In file {}: {}'.format(filename, e.msg))
return env
@ -55,9 +69,10 @@ class Environment(dict):
env_file_path = os.path.join(base_dir, '.env')
try:
return cls(env_vars_from_file(env_file_path))
except ConfigurationError:
except EnvFileNotFound:
pass
return result
instance = _initialize()
instance.update(os.environ)
return instance

View File

@ -19,6 +19,10 @@ class ConfigurationError(Exception):
return self.msg
class EnvFileNotFound(ConfigurationError):
pass
class DependencyError(ConfigurationError):
pass

View File

@ -9,6 +9,7 @@ import pytest
from compose.config.environment import env_vars_from_file
from compose.config.environment import Environment
from compose.config.errors import ConfigurationError
from tests import unittest
@ -52,3 +53,12 @@ class EnvironmentTest(unittest.TestCase):
assert env_vars_from_file(str(tmpdir.join('bom.env'))) == {
'PARK_BOM': '박봄'
}
def test_env_vars_from_file_whitespace(self):
tmpdir = pytest.ensuretemp('env_file')
self.addCleanup(tmpdir.remove)
with codecs.open('{}/whitespace.env'.format(str(tmpdir)), 'w', encoding='utf-8') as f:
f.write('WHITESPACE =yes\n')
with pytest.raises(ConfigurationError) as exc:
env_vars_from_file(str(tmpdir.join('whitespace.env')))
assert 'environment variable' in exc.exconly()