Show More
@@ -17,6 +17,12 b' import urllib2' | |||||
17 | import logging |
|
17 | import logging | |
18 | import posixpath |
|
18 | import posixpath | |
19 | import string |
|
19 | import string | |
|
20 | try: | |||
|
21 | # Python <=2.7 | |||
|
22 | from pipes import quote | |||
|
23 | except ImportError: | |||
|
24 | # Python 3.3+ | |||
|
25 | from shlex import quote | |||
20 |
|
26 | |||
21 | from dulwich.objects import Tag |
|
27 | from dulwich.objects import Tag | |
22 | from dulwich.repo import Repo, NotGitRepository |
|
28 | from dulwich.repo import Repo, NotGitRepository | |
@@ -654,7 +660,7 b' class GitRepository(BaseRepository):' | |||||
654 | cmd.append('--bare') |
|
660 | cmd.append('--bare') | |
655 | elif not update_after_clone: |
|
661 | elif not update_after_clone: | |
656 | cmd.append('--no-checkout') |
|
662 | cmd.append('--no-checkout') | |
657 |
cmd += ['--', |
|
663 | cmd += ['--', quote(url), self.path] | |
658 | cmd = ' '.join(cmd) |
|
664 | cmd = ' '.join(cmd) | |
659 | # If error occurs run_git_command raises RepositoryError already |
|
665 | # If error occurs run_git_command raises RepositoryError already | |
660 | self.run_git_command(cmd) |
|
666 | self.run_git_command(cmd) | |
@@ -664,7 +670,7 b' class GitRepository(BaseRepository):' | |||||
664 | Tries to pull changes from external location. |
|
670 | Tries to pull changes from external location. | |
665 | """ |
|
671 | """ | |
666 | url = self._get_url(url) |
|
672 | url = self._get_url(url) | |
667 | cmd = ['pull', "--ff-only", url] |
|
673 | cmd = ['pull', "--ff-only", quote(url)] | |
668 | cmd = ' '.join(cmd) |
|
674 | cmd = ' '.join(cmd) | |
669 | # If error occurs run_git_command raises RepositoryError already |
|
675 | # If error occurs run_git_command raises RepositoryError already | |
670 | self.run_git_command(cmd) |
|
676 | self.run_git_command(cmd) | |
@@ -674,13 +680,13 b' class GitRepository(BaseRepository):' | |||||
674 | Tries to pull changes from external location. |
|
680 | Tries to pull changes from external location. | |
675 | """ |
|
681 | """ | |
676 | url = self._get_url(url) |
|
682 | url = self._get_url(url) | |
677 | so, se = self.run_git_command('ls-remote -h %s' % url) |
|
683 | so, se = self.run_git_command('ls-remote -h %s' % quote(url)) | |
678 | refs = [] |
|
684 | refs = [] | |
679 | for line in (x for x in so.splitlines()): |
|
685 | for line in (x for x in so.splitlines()): | |
680 | sha, ref = line.split('\t') |
|
686 | sha, ref = line.split('\t') | |
681 | refs.append(ref) |
|
687 | refs.append(ref) | |
682 | refs = ' '.join(('+%s:%s' % (r, r) for r in refs)) |
|
688 | refs = ' '.join(('+%s:%s' % (r, r) for r in refs)) | |
683 | cmd = '''fetch %s -- %s''' % (url, refs) |
|
689 | cmd = '''fetch %s -- %s''' % (quote(url), refs) | |
684 | self.run_git_command(cmd) |
|
690 | self.run_git_command(cmd) | |
685 |
|
691 | |||
686 | def _update_server_info(self): |
|
692 | def _update_server_info(self): |
@@ -3,6 +3,7 b' from __future__ import with_statement' | |||||
3 | import os |
|
3 | import os | |
4 | import mock |
|
4 | import mock | |
5 | import datetime |
|
5 | import datetime | |
|
6 | import urllib2 | |||
6 | from kallithea.lib.vcs.backends.git import GitRepository, GitChangeset |
|
7 | from kallithea.lib.vcs.backends.git import GitRepository, GitChangeset | |
7 | from kallithea.lib.vcs.exceptions import RepositoryError, VCSError, NodeDoesNotExistError |
|
8 | from kallithea.lib.vcs.exceptions import RepositoryError, VCSError, NodeDoesNotExistError | |
8 | from kallithea.lib.vcs.nodes import NodeKind, FileNode, DirNode, NodeState |
|
9 | from kallithea.lib.vcs.nodes import NodeKind, FileNode, DirNode, NodeState | |
@@ -26,6 +27,32 b' class GitRepositoryTest(unittest.TestCas' | |||||
26 | wrong_repo_path = '/tmp/errorrepo' |
|
27 | wrong_repo_path = '/tmp/errorrepo' | |
27 | self.assertRaises(RepositoryError, GitRepository, wrong_repo_path) |
|
28 | self.assertRaises(RepositoryError, GitRepository, wrong_repo_path) | |
28 |
|
29 | |||
|
30 | def test_git_cmd_injection(self): | |||
|
31 | remote_repo_url = 'https://github.com/codeinn/vcs.git' | |||
|
32 | inject_remote = '%s;%s' % (remote_repo_url, '; echo "Cake";') | |||
|
33 | with self.assertRaises(urllib2.URLError): | |||
|
34 | # Should fail because URL will be: https://github.com/codeinn/vcs.git%3B%3B%20echo%20%22Cake%22%3B | |||
|
35 | urlerror_fail_repo = GitRepository(get_new_dir('injection-repo'), src_url=inject_remote, update_after_clone=True, create=True) | |||
|
36 | ||||
|
37 | with self.assertRaises(RepositoryError): | |||
|
38 | # Should fail on direct clone call, which as of this writing does not happen outside of class | |||
|
39 | clone_fail_repo = GitRepository(get_new_dir('injection-repo'), create=True) | |||
|
40 | clone_fail_repo.clone(inject_remote, update_after_clone=True,) | |||
|
41 | ||||
|
42 | successfully_cloned = GitRepository(get_new_dir('injection-repo'), src_url=remote_repo_url, update_after_clone=True, create=True) | |||
|
43 | # Repo should have been created | |||
|
44 | self.assertFalse(successfully_cloned._repo.bare) | |||
|
45 | ||||
|
46 | with self.assertRaises(RepositoryError): | |||
|
47 | # Should fail because URL will be invalid repo | |||
|
48 | inject_remote_var = '%s;%s' % (remote_repo_url, '; echo $PATH;') | |||
|
49 | successfully_cloned.fetch(inject_remote_var) | |||
|
50 | ||||
|
51 | with self.assertRaises(RepositoryError): | |||
|
52 | # Should fail because URL will be invalid repo | |||
|
53 | inject_remote_ls = '%s;%s' % (remote_repo_url, '; ls -1 ~;') | |||
|
54 | successfully_cloned.pull(inject_remote_ls) | |||
|
55 | ||||
29 | def test_repo_clone(self): |
|
56 | def test_repo_clone(self): | |
30 | self.__check_for_existing_repo() |
|
57 | self.__check_for_existing_repo() | |
31 | repo = GitRepository(TEST_GIT_REPO) |
|
58 | repo = GitRepository(TEST_GIT_REPO) |
General Comments 0
You need to be logged in to leave comments.
Login now