aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--setuptools/config.py12
-rw-r--r--setuptools/tests/test_config.py12
2 files changed, 23 insertions, 1 deletions
diff --git a/setuptools/config.py b/setuptools/config.py
index d8513a72..c2319ed5 100644
--- a/setuptools/config.py
+++ b/setuptools/config.py
@@ -128,7 +128,10 @@ class ConfigHandler(object):
@classmethod
def _parse_file(cls, value):
"""Represents value as a string, allowing including text
- from nearest files using include().
+ from nearest files using `file:` directive.
+
+ Directive is sandboxed and won't reach anything outside
+ directory with setup.py.
Examples:
include: LICENSE
@@ -144,7 +147,14 @@ class ConfigHandler(object):
if not value.startswith(include_directive):
return value
+ current_directory = os.getcwd()
+
filepath = value.replace(include_directive, '').strip()
+ filepath = os.path.abspath(filepath)
+
+ if not filepath.startswith(current_directory):
+ raise DistutilsOptionError(
+ '`file:` directive can not access %s' % filepath)
if os.path.isfile(filepath):
with io.open(filepath, encoding='utf-8') as f:
diff --git a/setuptools/tests/test_config.py b/setuptools/tests/test_config.py
index 08c5bd19..9fb55b06 100644
--- a/setuptools/tests/test_config.py
+++ b/setuptools/tests/test_config.py
@@ -86,6 +86,18 @@ class TestMetadata:
assert metadata.name == 'fake_name'
assert metadata.keywords == ['one', 'two']
+ def test_file_sandboxed(self, tmpdir):
+
+ fake_env(
+ tmpdir,
+ '[metadata]\n'
+ 'long_description = file: ../../README\n'
+ )
+
+ with get_dist(tmpdir, parse=False) as dist:
+ with pytest.raises(DistutilsOptionError):
+ dist.parse_config_files() # file: out of sandbox
+
def test_aliases(self, tmpdir):
fake_env(