diff --git a/project.py b/project.py index 185507c0..a305d720 100644 --- a/project.py +++ b/project.py @@ -382,7 +382,12 @@ class _LinkFile(object): Handles wild cards on the src linking all of the files in the source in to the destination directory. """ - src = _SafeExpandPath(self.git_worktree, self.src) + # Some people use src="." to create stable links to projects. Lets allow + # that but reject all other uses of "." to keep things simple. + if self.src == '.': + src = self.git_worktree + else: + src = _SafeExpandPath(self.git_worktree, self.src) if os.path.exists(src): # Entity exists so just a simple one to one link operation. diff --git a/tests/test_project.py b/tests/test_project.py index 6d82da11..dc41f4c0 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -314,6 +314,14 @@ class LinkFile(CopyLinkTestCase): lf._Link() self.assertExists(os.path.join(self.topdir, 'foo')) + def test_src_self(self): + """Link to the project itself.""" + dest = os.path.join(self.topdir, 'foo', 'bar') + lf = self.LinkFile('.', 'foo/bar') + lf._Link() + self.assertExists(dest) + self.assertEqual('../git-project', os.readlink(dest)) + def test_dest_subdir(self): """Link a file to a subdir of a checkout.""" src = os.path.join(self.worktree, 'foo.txt') @@ -323,6 +331,21 @@ class LinkFile(CopyLinkTestCase): lf._Link() self.assertExists(os.path.join(self.topdir, 'sub', 'dir', 'foo', 'bar')) + def test_src_block_relative(self): + """Do not allow relative symlinks.""" + BAD_SOURCES = ( + './', + '..', + '../', + 'foo/.', + 'foo/./bar', + 'foo/..', + 'foo/../foo', + ) + for src in BAD_SOURCES: + lf = self.LinkFile(src, 'foo') + self.assertRaises(error.ManifestInvalidPathError, lf._Link) + def test_update(self): """Make sure changed targets get updated.""" dest = os.path.join(self.topdir, 'sym')