From ed93e0d0d9697d4aa1aeaff91701011443dcb2cf Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Wed, 24 Oct 2018 12:26:28 +0300 Subject: [PATCH] stage: check that cwd is inside the current project Fixes #1253 Signed-off-by: Ruslan Kuprieiev --- dvc/stage.py | 15 +++++++++++++++ tests/test_run.py | 7 +++++++ 2 files changed, 22 insertions(+) diff --git a/dvc/stage.py b/dvc/stage.py index 9020b18f9..ff2dacde0 100644 --- a/dvc/stage.py +++ b/dvc/stage.py @@ -40,6 +40,12 @@ class StageFileBadNameError(DvcException): super(StageFileBadNameError, self).__init__(msg) +class StageBadCwdError(DvcException): + def __init__(self, cwd): + msg = "Stage cwd '{}' is outside of the current dvc project" + super(StageBadCwdError, self).__init__(msg.format(cwd)) + + class MissingDep(DvcException): def __init__(self, deps): assert len(deps) > 0 @@ -275,6 +281,13 @@ class Stage(object): return (fname, cwd) + @staticmethod + def _check_inside_project(project, cwd): + assert project is not None + proj_dir = os.path.realpath(project.root_dir) + if not os.path.realpath(cwd).startswith(proj_dir): + raise StageBadCwdError(cwd) + @staticmethod def loads(project=None, cmd=None, @@ -305,6 +318,8 @@ class Stage(object): fname, cwd = Stage._stage_fname_cwd(fname, cwd, stage.outs, add=add) + Stage._check_inside_project(project, cwd) + cwd = os.path.abspath(cwd) path = os.path.join(cwd, fname) diff --git a/tests/test_run.py b/tests/test_run.py index 4c14940fd..b42c90605 100644 --- a/tests/test_run.py +++ b/tests/test_run.py @@ -4,6 +4,7 @@ import filecmp from dvc.main import main from dvc.utils import file_md5 from dvc.stage import Stage, StageFileBadNameError, MissingDep +from dvc.stage import StageBadCwdError from dvc.command.run import CmdRun from dvc.exceptions import OutputDuplicationError, CircularDependencyError @@ -101,6 +102,12 @@ class TestRunCircularDependency(TestDvc): outs=[self.FOO], fname='circular-dependency.dvc') +class TestRunBadCwd(TestDvc): + def test(self): + with self.assertRaises(StageBadCwdError): + self.dvc.run(cmd='', + cwd=self.mkdtemp()) + class TestCmdRun(TestDvc): def test_run(self):