mirror of https://github.com/docker/compose.git
reject environment variable that contains white spaces
Signed-off-by: Hiroshi Ioka <hirochachacha@gmail.com>
This commit is contained in:
parent
0fc3b51b50
commit
afc161a0b1
|
@ -5,22 +5,33 @@ import codecs
|
||||||
import contextlib
|
import contextlib
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import string
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from ..const import IS_WINDOWS_PLATFORM
|
from ..const import IS_WINDOWS_PLATFORM
|
||||||
from .errors import ConfigurationError
|
from .errors import ConfigurationError
|
||||||
|
from .errors import EnvFileNotFound
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
whitespace = set(string.whitespace)
|
||||||
|
|
||||||
|
|
||||||
def split_env(env):
|
def split_env(env):
|
||||||
if isinstance(env, six.binary_type):
|
if isinstance(env, six.binary_type):
|
||||||
env = env.decode('utf-8', 'replace')
|
env = env.decode('utf-8', 'replace')
|
||||||
|
key = value = None
|
||||||
if '=' in env:
|
if '=' in env:
|
||||||
return env.split('=', 1)
|
key, value = env.split('=', 1)
|
||||||
else:
|
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):
|
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.
|
Read in a line delimited file of environment variables.
|
||||||
"""
|
"""
|
||||||
if not os.path.exists(filename):
|
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):
|
elif not os.path.isfile(filename):
|
||||||
raise ConfigurationError("%s is not a file." % (filename))
|
raise EnvFileNotFound("%s is not a file." % (filename))
|
||||||
env = {}
|
env = {}
|
||||||
with contextlib.closing(codecs.open(filename, 'r', 'utf-8-sig')) as fileobj:
|
with contextlib.closing(codecs.open(filename, 'r', 'utf-8-sig')) as fileobj:
|
||||||
for line in fileobj:
|
for line in fileobj:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if line and not line.startswith('#'):
|
if line and not line.startswith('#'):
|
||||||
k, v = split_env(line)
|
try:
|
||||||
env[k] = v
|
k, v = split_env(line)
|
||||||
|
env[k] = v
|
||||||
|
except ConfigurationError as e:
|
||||||
|
raise ConfigurationError('In file {}: {}'.format(filename, e.msg))
|
||||||
return env
|
return env
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,9 +69,10 @@ class Environment(dict):
|
||||||
env_file_path = os.path.join(base_dir, '.env')
|
env_file_path = os.path.join(base_dir, '.env')
|
||||||
try:
|
try:
|
||||||
return cls(env_vars_from_file(env_file_path))
|
return cls(env_vars_from_file(env_file_path))
|
||||||
except ConfigurationError:
|
except EnvFileNotFound:
|
||||||
pass
|
pass
|
||||||
return result
|
return result
|
||||||
|
|
||||||
instance = _initialize()
|
instance = _initialize()
|
||||||
instance.update(os.environ)
|
instance.update(os.environ)
|
||||||
return instance
|
return instance
|
||||||
|
|
|
@ -19,6 +19,10 @@ class ConfigurationError(Exception):
|
||||||
return self.msg
|
return self.msg
|
||||||
|
|
||||||
|
|
||||||
|
class EnvFileNotFound(ConfigurationError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DependencyError(ConfigurationError):
|
class DependencyError(ConfigurationError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import pytest
|
||||||
|
|
||||||
from compose.config.environment import env_vars_from_file
|
from compose.config.environment import env_vars_from_file
|
||||||
from compose.config.environment import Environment
|
from compose.config.environment import Environment
|
||||||
|
from compose.config.errors import ConfigurationError
|
||||||
from tests import unittest
|
from tests import unittest
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,3 +53,12 @@ class EnvironmentTest(unittest.TestCase):
|
||||||
assert env_vars_from_file(str(tmpdir.join('bom.env'))) == {
|
assert env_vars_from_file(str(tmpdir.join('bom.env'))) == {
|
||||||
'PARK_BOM': '박봄'
|
'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()
|
||||||
|
|
Loading…
Reference in New Issue