Change-Id: I1fcedb5c5456300778d53d97caa6a60235fa1511
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/4059
Reviewed-by: Anish Swaminathan <anishs@vmware.com>
Tested-by: Anish Swaminathan <anishs@vmware.com>
1 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,53 +0,0 @@ |
1 |
-+++ b/mercurial/subrepo.py Sun Mar 20 21:52:21 2016 -0700 |
|
2 |
-@@ -1383,6 +1383,11 @@ |
|
3 |
- are not supported and very probably fail. |
|
4 |
- """ |
|
5 |
- self.ui.debug('%s: git %s\n' % (self._relpath, ' '.join(commands))) |
|
6 |
-+ if env is None: |
|
7 |
-+ env = os.environ.copy() |
|
8 |
-+ # fix for Git CVE-2015-7545 |
|
9 |
-+ if 'GIT_ALLOW_PROTOCOL' not in env: |
|
10 |
-+ env['GIT_ALLOW_PROTOCOL'] = 'file:git:http:https:ssh' |
|
11 |
- # unless ui.quiet is set, print git's stderr, |
|
12 |
- # which is mostly progress and useful info |
|
13 |
- errpipe = None |
|
14 |
-+++ b/tests/test-subrepo-git.t Sun Mar 20 21:52:21 2016 -0700 |
|
15 |
-@@ -1132,4 +1132,36 @@ |
|
16 |
- ? s/foobar.orig |
|
17 |
- ? s/snake.python.orig |
|
18 |
- |
|
19 |
-+test for Git CVE-2016-3068 |
|
20 |
-+ $ hg init malicious-subrepository |
|
21 |
-+ $ cd malicious-subrepository |
|
22 |
-+ $ echo "s = [git]ext::sh -c echo% pwned% >&2" > .hgsub |
|
23 |
-+ $ git init s |
|
24 |
-+ Initialized empty Git repository in $TESTTMP/tc/malicious-subrepository/s/.git/ |
|
25 |
-+ $ cd s |
|
26 |
-+ $ git commit --allow-empty -m 'empty' |
|
27 |
-+ [master (root-commit) 153f934] empty |
|
28 |
- $ cd .. |
|
29 |
-+ $ hg add .hgsub |
|
30 |
-+ $ hg commit -m "add subrepo" |
|
31 |
-+ $ cd .. |
|
32 |
-+ $ env -u GIT_ALLOW_PROTOCOL hg clone malicious-subrepository malicious-subrepository-protected |
|
33 |
-+ Cloning into '$TESTTMP/tc/malicious-subrepository-protected/s'... |
|
34 |
-+ fatal: transport 'ext' not allowed |
|
35 |
-+ updating to branch default |
|
36 |
-+ cloning subrepo s from ext::sh -c echo% pwned% >&2 |
|
37 |
-+ abort: git clone error 128 in s (in subrepo s) |
|
38 |
-+ [255] |
|
39 |
-+ |
|
40 |
-+whitelisting of ext should be respected (that's the git submodule behaviour) |
|
41 |
-+ $ env GIT_ALLOW_PROTOCOL=ext hg clone malicious-subrepository malicious-subrepository-clone-allowed |
|
42 |
-+ Cloning into '$TESTTMP/tc/malicious-subrepository-clone-allowed/s'... |
|
43 |
-+ pwned |
|
44 |
-+ fatal: Could not read from remote repository. |
|
45 |
-+ |
|
46 |
-+ Please make sure you have the correct access rights |
|
47 |
-+ and the repository exists. |
|
48 |
-+ updating to branch default |
|
49 |
-+ cloning subrepo s from ext::sh -c echo% pwned% >&2 |
|
50 |
-+ abort: git clone error 128 in s (in subrepo s) |
|
51 |
-+ [255] |
52 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,50 +0,0 @@ |
1 |
-+++ b/hgext/convert/git.py Tue Mar 22 17:05:11 2016 -0700 |
|
2 |
-@@ -11,7 +11,7 @@ |
|
3 |
- from mercurial.node import hex, nullid |
|
4 |
- from mercurial.i18n import _ |
|
5 |
- |
|
6 |
--from common import NoRepo, commit, converter_source, checktool |
|
7 |
-+from common import NoRepo, commit, converter_source, checktool, commandline |
|
8 |
- |
|
9 |
- class submodule(object): |
|
10 |
- def __init__(self, path, node, url): |
|
11 |
-@@ -25,7 +25,7 @@ |
|
12 |
- def hgsubstate(self): |
|
13 |
- return "%s %s" % (self.node, self.path) |
|
14 |
- |
|
15 |
--class convert_git(converter_source): |
|
16 |
-+class convert_git(converter_source, commandline): |
|
17 |
- # Windows does not support GIT_DIR= construct while other systems |
|
18 |
- # cannot remove environment variable. Just assume none have |
|
19 |
- # both issues. |
|
20 |
-@@ -71,6 +71,21 @@ |
|
21 |
- def gitpipe(self, s): |
|
22 |
- return util.popen3('GIT_DIR=%s %s' % (self.path, s)) |
|
23 |
- |
|
24 |
-+ def _gitcmd(self, cmd, *args, **kwargs): |
|
25 |
-+ return cmd('--git-dir=%s' % self.path, *args, **kwargs) |
|
26 |
-+ |
|
27 |
-+ def gitrun0(self, *args, **kwargs): |
|
28 |
-+ return self._gitcmd(self.run0, *args, **kwargs) |
|
29 |
-+ |
|
30 |
-+ def gitrun(self, *args, **kwargs): |
|
31 |
-+ return self._gitcmd(self.run, *args, **kwargs) |
|
32 |
-+ |
|
33 |
-+ def gitrunlines0(self, *args, **kwargs): |
|
34 |
-+ return self._gitcmd(self.runlines0, *args, **kwargs) |
|
35 |
-+ |
|
36 |
-+ def gitrunlines(self, *args, **kwargs): |
|
37 |
-+ return self._gitcmd(self.runlines, *args, **kwargs) |
|
38 |
-+ |
|
39 |
- def popen_with_stderr(self, s): |
|
40 |
- p = subprocess.Popen(s, shell=True, bufsize=-1, |
|
41 |
- close_fds=util.closefds, |
|
42 |
-@@ -88,6 +103,7 @@ |
|
43 |
- |
|
44 |
- def __init__(self, ui, path, revs=None): |
|
45 |
- super(convert_git, self).__init__(ui, path, revs=revs) |
|
46 |
-+ commandline.__init__(self, ui, 'git') |
|
47 |
- |
|
48 |
- if os.path.isdir(path + "/.git"): |
|
49 |
- path += "/.git" |
50 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,173 +0,0 @@ |
1 |
-+++ b/hgext/convert/git.py Tue Mar 22 17:05:11 2016 -0700 |
|
2 |
-@@ -115,13 +115,13 @@ |
|
3 |
- if similarity < 0 or similarity > 100: |
|
4 |
- raise error.Abort(_('similarity must be between 0 and 100')) |
|
5 |
- if similarity > 0: |
|
6 |
-- self.simopt = '-C%d%%' % similarity |
|
7 |
-+ self.simopt = ['-C%d%%' % similarity] |
|
8 |
- findcopiesharder = ui.configbool('convert', 'git.findcopiesharder', |
|
9 |
- False) |
|
10 |
- if findcopiesharder: |
|
11 |
-- self.simopt += ' --find-copies-harder' |
|
12 |
-+ self.simopt.append('--find-copies-harder') |
|
13 |
- else: |
|
14 |
-- self.simopt = '' |
|
15 |
-+ self.simopt = [] |
|
16 |
- |
|
17 |
- checktool('git', 'git') |
|
18 |
- |
|
19 |
-@@ -136,14 +136,14 @@ |
|
20 |
- |
|
21 |
- def getheads(self): |
|
22 |
- if not self.revs: |
|
23 |
-- heads, ret = self.gitread('git rev-parse --branches --remotes') |
|
24 |
-- heads = heads.splitlines() |
|
25 |
-- if ret: |
|
26 |
-+ output, status = self.gitrun('rev-parse', '--branches', '--remotes') |
|
27 |
-+ heads = output.splitlines() |
|
28 |
-+ if status: |
|
29 |
- raise error.Abort(_('cannot retrieve git heads')) |
|
30 |
- else: |
|
31 |
- heads = [] |
|
32 |
- for rev in self.revs: |
|
33 |
-- rawhead, ret = self.gitread("git rev-parse --verify %s" % rev) |
|
34 |
-+ rawhead, ret = self.gitrun('rev-parse', '--verify', rev) |
|
35 |
- heads.append(rawhead[:-1]) |
|
36 |
- if ret: |
|
37 |
- raise error.Abort(_('cannot retrieve git head "%s"') % rev) |
|
38 |
-@@ -203,7 +203,7 @@ |
|
39 |
- self.submodules.append(submodule(s['path'], '', s['url'])) |
|
40 |
- |
|
41 |
- def retrievegitmodules(self, version): |
|
42 |
-- modules, ret = self.gitread("git show %s:%s" % (version, '.gitmodules')) |
|
43 |
-+ modules, ret = self.gitrun('show', '%s:%s' % (version, '.gitmodules')) |
|
44 |
- if ret: |
|
45 |
- # This can happen if a file is in the repo that has permissions |
|
46 |
- # 160000, but there is no .gitmodules file. |
|
47 |
-@@ -219,7 +219,7 @@ |
|
48 |
- return |
|
49 |
- |
|
50 |
- for m in self.submodules: |
|
51 |
-- node, ret = self.gitread("git rev-parse %s:%s" % (version, m.path)) |
|
52 |
-+ node, ret = self.gitrun('rev-parse', '%s:%s' % (version, m.path)) |
|
53 |
- if ret: |
|
54 |
- continue |
|
55 |
- m.node = node.strip() |
|
56 |
-@@ -228,15 +228,17 @@ |
|
57 |
- if full: |
|
58 |
- raise error.Abort(_("convert from git does not support --full")) |
|
59 |
- self.modecache = {} |
|
60 |
-- fh = self.gitopen("git diff-tree -z --root -m -r %s %s" % ( |
|
61 |
-- self.simopt, version)) |
|
62 |
-+ cmd = ['diff-tree','-z', '--root', '-m', '-r'] + self.simopt + [version] |
|
63 |
-+ output, status = self.gitrun(*cmd) |
|
64 |
-+ if status: |
|
65 |
-+ raise error.Abort(_('cannot read changes in %s') % version) |
|
66 |
- changes = [] |
|
67 |
- copies = {} |
|
68 |
- seen = set() |
|
69 |
- entry = None |
|
70 |
- subexists = [False] |
|
71 |
- subdeleted = [False] |
|
72 |
-- difftree = fh.read().split('\x00') |
|
73 |
-+ difftree = output.split('\x00') |
|
74 |
- lcount = len(difftree) |
|
75 |
- i = 0 |
|
76 |
- |
|
77 |
-@@ -298,8 +300,6 @@ |
|
78 |
- if f != '.gitmodules' and fdest != '.gitmodules': |
|
79 |
- copies[fdest] = f |
|
80 |
- entry = None |
|
81 |
-- if fh.close(): |
|
82 |
-- raise error.Abort(_('cannot read changes in %s') % version) |
|
83 |
- |
|
84 |
- if subexists[0]: |
|
85 |
- if subdeleted[0]: |
|
86 |
-@@ -345,17 +345,23 @@ |
|
87 |
- return c |
|
88 |
- |
|
89 |
- def numcommits(self): |
|
90 |
-- return len([None for _ in self.gitopen('git rev-list --all')]) |
|
91 |
-+ output, ret = self.gitrunlines('rev-list', '--all') |
|
92 |
-+ if ret: |
|
93 |
-+ raise error.Abort(_('cannot retrieve number of commits in %s') \ |
|
94 |
-+ % self.path) |
|
95 |
-+ return len(output) |
|
96 |
- |
|
97 |
- def gettags(self): |
|
98 |
- tags = {} |
|
99 |
- alltags = {} |
|
100 |
-- fh = self.gitopen('git ls-remote --tags "%s"' % self.path, |
|
101 |
-- err=subprocess.STDOUT) |
|
102 |
-+ output, status = self.gitrunlines('ls-remote', '--tags', self.path) |
|
103 |
-+ |
|
104 |
-+ if status: |
|
105 |
-+ raise error.Abort(_('cannot read tags from %s') % self.path) |
|
106 |
- prefix = 'refs/tags/' |
|
107 |
- |
|
108 |
- # Build complete list of tags, both annotated and bare ones |
|
109 |
-- for line in fh: |
|
110 |
-+ for line in output: |
|
111 |
- line = line.strip() |
|
112 |
- if line.startswith("error:") or line.startswith("fatal:"): |
|
113 |
- raise error.Abort(_('cannot read tags from %s') % self.path) |
|
114 |
-@@ -363,8 +369,6 @@ |
|
115 |
- if not tag.startswith(prefix): |
|
116 |
- continue |
|
117 |
- alltags[tag[len(prefix):]] = node |
|
118 |
-- if fh.close(): |
|
119 |
-- raise error.Abort(_('cannot read tags from %s') % self.path) |
|
120 |
- |
|
121 |
- # Filter out tag objects for annotated tag refs |
|
122 |
- for tag in alltags: |
|
123 |
-@@ -381,18 +385,20 @@ |
|
124 |
- def getchangedfiles(self, version, i): |
|
125 |
- changes = [] |
|
126 |
- if i is None: |
|
127 |
-- fh = self.gitopen("git diff-tree --root -m -r %s" % version) |
|
128 |
-- for l in fh: |
|
129 |
-+ output, status = self.gitrunlines('diff-tree', '--root', '-m', |
|
130 |
-+ '-r', version) |
|
131 |
-+ if status: |
|
132 |
-+ raise error.Abort(_('cannot read changes in %s') % version) |
|
133 |
-+ for l in output: |
|
134 |
- if "\t" not in l: |
|
135 |
- continue |
|
136 |
- m, f = l[:-1].split("\t") |
|
137 |
- changes.append(f) |
|
138 |
- else: |
|
139 |
-- fh = self.gitopen('git diff-tree --name-only --root -r %s ' |
|
140 |
-- '"%s^%s" --' % (version, version, i + 1)) |
|
141 |
-- changes = [f.rstrip('\n') for f in fh] |
|
142 |
-- if fh.close(): |
|
143 |
-- raise error.Abort(_('cannot read changes in %s') % version) |
|
144 |
-+ output, status = self.gitrunlines('diff-tree', '--name-only', |
|
145 |
-+ '--root', '-r', version, |
|
146 |
-+ '%s^%s' % (version, i + 1), '--') |
|
147 |
-+ changes = [f.rstrip('\n') for f in output] |
|
148 |
- |
|
149 |
- return changes |
|
150 |
- |
|
151 |
-@@ -412,8 +418,8 @@ |
|
152 |
- ]) |
|
153 |
- |
|
154 |
- try: |
|
155 |
-- fh = self.gitopen('git show-ref', err=subprocess.PIPE) |
|
156 |
-- for line in fh: |
|
157 |
-+ output, status = self.gitrunlines('show-ref') |
|
158 |
-+ for line in output: |
|
159 |
- line = line.strip() |
|
160 |
- rev, name = line.split(None, 1) |
|
161 |
- # Process each type of branch |
|
162 |
-+++ b/tests/test-convert-git.t Tue Mar 22 17:05:11 2016 -0700 |
|
163 |
-@@ -714,7 +714,7 @@ |
|
164 |
- $ COMMIT_OBJ=1c/0ce3c5886f83a1d78a7b517cdff5cf9ca17bdd |
|
165 |
- $ mv git-repo4/.git/objects/$COMMIT_OBJ git-repo4/.git/objects/$COMMIT_OBJ.tmp |
|
166 |
- $ hg convert git-repo4 git-repo4-broken-hg 2>&1 | grep 'abort:' |
|
167 |
-- abort: cannot read tags from git-repo4/.git |
|
168 |
-+ abort: cannot retrieve number of commits in git-repo4/.git |
|
169 |
- $ mv git-repo4/.git/objects/$COMMIT_OBJ.tmp git-repo4/.git/objects/$COMMIT_OBJ |
|
170 |
- damage git repository by renaming a blob object |
|
171 |
- |
172 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,59 +0,0 @@ |
1 |
-+++ b/hgext/convert/git.py Tue Mar 22 17:05:11 2016 -0700 |
|
2 |
-@@ -30,23 +30,6 @@ |
|
3 |
- # cannot remove environment variable. Just assume none have |
|
4 |
- # both issues. |
|
5 |
- if util.safehasattr(os, 'unsetenv'): |
|
6 |
-- def gitopen(self, s, err=None): |
|
7 |
-- prevgitdir = os.environ.get('GIT_DIR') |
|
8 |
-- os.environ['GIT_DIR'] = self.path |
|
9 |
-- try: |
|
10 |
-- if err == subprocess.PIPE: |
|
11 |
-- (stdin, stdout, stderr) = util.popen3(s) |
|
12 |
-- return stdout |
|
13 |
-- elif err == subprocess.STDOUT: |
|
14 |
-- return self.popen_with_stderr(s) |
|
15 |
-- else: |
|
16 |
-- return util.popen(s, 'rb') |
|
17 |
-- finally: |
|
18 |
-- if prevgitdir is None: |
|
19 |
-- del os.environ['GIT_DIR'] |
|
20 |
-- else: |
|
21 |
-- os.environ['GIT_DIR'] = prevgitdir |
|
22 |
-- |
|
23 |
- def gitpipe(self, s): |
|
24 |
- prevgitdir = os.environ.get('GIT_DIR') |
|
25 |
- os.environ['GIT_DIR'] = self.path |
|
26 |
-@@ -59,15 +42,6 @@ |
|
27 |
- os.environ['GIT_DIR'] = prevgitdir |
|
28 |
- |
|
29 |
- else: |
|
30 |
-- def gitopen(self, s, err=None): |
|
31 |
-- if err == subprocess.PIPE: |
|
32 |
-- (sin, so, se) = util.popen3('GIT_DIR=%s %s' % (self.path, s)) |
|
33 |
-- return so |
|
34 |
-- elif err == subprocess.STDOUT: |
|
35 |
-- return self.popen_with_stderr(s) |
|
36 |
-- else: |
|
37 |
-- return util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb') |
|
38 |
-- |
|
39 |
- def gitpipe(self, s): |
|
40 |
- return util.popen3('GIT_DIR=%s %s' % (self.path, s)) |
|
41 |
- |
|
42 |
-@@ -86,16 +60,6 @@ |
|
43 |
- def gitrunlines(self, *args, **kwargs): |
|
44 |
- return self._gitcmd(self.runlines, *args, **kwargs) |
|
45 |
- |
|
46 |
-- def popen_with_stderr(self, s): |
|
47 |
-- p = subprocess.Popen(s, shell=True, bufsize=-1, |
|
48 |
-- close_fds=util.closefds, |
|
49 |
-- stdin=subprocess.PIPE, |
|
50 |
-- stdout=subprocess.PIPE, |
|
51 |
-- stderr=subprocess.STDOUT, |
|
52 |
-- universal_newlines=False, |
|
53 |
-- env=None) |
|
54 |
-- return p.stdout |
|
55 |
-- |
|
56 |
- def gitread(self, s): |
|
57 |
- fh = self.gitopen(s) |
|
58 |
- data = fh.read() |
59 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,55 +0,0 @@ |
1 |
-+++ b/hgext/convert/common.py Tue Mar 22 17:05:11 2016 -0700 |
|
2 |
-@@ -341,6 +341,9 @@ |
|
3 |
- def _run2(self, cmd, *args, **kwargs): |
|
4 |
- return self._dorun(util.popen2, cmd, *args, **kwargs) |
|
5 |
- |
|
6 |
-+ def _run3(self, cmd, *args, **kwargs): |
|
7 |
-+ return self._dorun(util.popen3, cmd, *args, **kwargs) |
|
8 |
-+ |
|
9 |
- def _dorun(self, openfunc, cmd, *args, **kwargs): |
|
10 |
- cmdline = self._cmdline(cmd, *args, **kwargs) |
|
11 |
- self.ui.debug('running: %s\n' % (cmdline,)) |
|
12 |
-+++ b/hgext/convert/git.py Tue Mar 22 17:05:11 2016 -0700 |
|
13 |
-@@ -29,21 +29,6 @@ |
|
14 |
- # Windows does not support GIT_DIR= construct while other systems |
|
15 |
- # cannot remove environment variable. Just assume none have |
|
16 |
- # both issues. |
|
17 |
-- if util.safehasattr(os, 'unsetenv'): |
|
18 |
-- def gitpipe(self, s): |
|
19 |
-- prevgitdir = os.environ.get('GIT_DIR') |
|
20 |
-- os.environ['GIT_DIR'] = self.path |
|
21 |
-- try: |
|
22 |
-- return util.popen3(s) |
|
23 |
-- finally: |
|
24 |
-- if prevgitdir is None: |
|
25 |
-- del os.environ['GIT_DIR'] |
|
26 |
-- else: |
|
27 |
-- os.environ['GIT_DIR'] = prevgitdir |
|
28 |
-- |
|
29 |
-- else: |
|
30 |
-- def gitpipe(self, s): |
|
31 |
-- return util.popen3('GIT_DIR=%s %s' % (self.path, s)) |
|
32 |
- |
|
33 |
- def _gitcmd(self, cmd, *args, **kwargs): |
|
34 |
- return cmd('--git-dir=%s' % self.path, *args, **kwargs) |
|
35 |
-@@ -60,6 +45,9 @@ |
|
36 |
- def gitrunlines(self, *args, **kwargs): |
|
37 |
- return self._gitcmd(self.runlines, *args, **kwargs) |
|
38 |
- |
|
39 |
-+ def gitpipe(self, *args, **kwargs): |
|
40 |
-+ return self._gitcmd(self._run3, *args, **kwargs) |
|
41 |
-+ |
|
42 |
- def gitread(self, s): |
|
43 |
- fh = self.gitopen(s) |
|
44 |
- data = fh.read() |
|
45 |
-@@ -92,7 +80,7 @@ |
|
46 |
- self.path = path |
|
47 |
- self.submodules = [] |
|
48 |
- |
|
49 |
-- self.catfilepipe = self.gitpipe('git cat-file --batch') |
|
50 |
-+ self.catfilepipe = self.gitpipe('cat-file', '--batch') |
|
51 |
- |
|
52 |
- def after(self): |
|
53 |
- for f in self.catfilepipe: |
54 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,23 +0,0 @@ |
1 |
-+++ b/tests/test-convert-git.t Tue Mar 22 17:27:27 2016 -0700 |
|
2 |
-@@ -729,3 +729,20 @@ |
|
3 |
- $ mv git-repo4/.git/objects/$TREE_OBJ git-repo4/.git/objects/$TREE_OBJ.tmp |
|
4 |
- $ hg convert git-repo4 git-repo4-broken-hg 2>&1 | grep 'abort:' |
|
5 |
- abort: cannot read changes in 1c0ce3c5886f83a1d78a7b517cdff5cf9ca17bdd |
|
6 |
-+ |
|
7 |
-+test for escaping the repo name (CVE-2016-3069) |
|
8 |
-+ |
|
9 |
-+ $ git init '`echo pwned >COMMAND-INJECTION`' |
|
10 |
-+ Initialized empty Git repository in $TESTTMP/`echo pwned >COMMAND-INJECTION`/.git/ |
|
11 |
-+ $ cd '`echo pwned >COMMAND-INJECTION`' |
|
12 |
-+ $ git commit -q --allow-empty -m 'empty' |
|
13 |
-+ $ cd .. |
|
14 |
-+ $ hg convert '`echo pwned >COMMAND-INJECTION`' 'converted' |
|
15 |
-+ initializing destination converted repository |
|
16 |
-+ scanning source... |
|
17 |
-+ sorting... |
|
18 |
-+ converting... |
|
19 |
-+ 0 empty |
|
20 |
-+ updating bookmarks |
|
21 |
-+ $ test -f COMMAND-INJECTION |
|
22 |
-+ [1] |
23 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,62 +0,0 @@ |
1 |
-+++ b/hgext/convert/git.py Wed Apr 06 22:57:46 2016 -0500 |
|
2 |
-@@ -57,6 +57,10 @@ class convert_git(converter_source, commandline): |
|
3 |
- super(convert_git, self).__init__(ui, path, revs=revs) |
|
4 |
- commandline.__init__(self, ui, 'git') |
|
5 |
- |
|
6 |
-+ # Pass an absolute path to git to prevent from ever being interpreted |
|
7 |
-+ # as a URL |
|
8 |
-+ path = os.path.abspath(path) |
|
9 |
-+ |
|
10 |
- if os.path.isdir(path + "/.git"): |
|
11 |
- path += "/.git" |
|
12 |
- if not os.path.exists(path + "/objects"): |
|
13 |
- |
|
14 |
-+++ b/tests/test-convert-git.t Wed Apr 06 22:57:46 2016 -0500 |
|
15 |
-@@ -714,7 +714,7 @@ |
|
16 |
- $ COMMIT_OBJ=1c/0ce3c5886f83a1d78a7b517cdff5cf9ca17bdd |
|
17 |
- $ mv git-repo4/.git/objects/$COMMIT_OBJ git-repo4/.git/objects/$COMMIT_OBJ.tmp |
|
18 |
- $ hg convert git-repo4 git-repo4-broken-hg 2>&1 | grep 'abort:' |
|
19 |
-- abort: cannot retrieve number of commits in git-repo4/.git |
|
20 |
-+ abort: cannot retrieve number of commits in $TESTTMP/git-repo4/.git |
|
21 |
- $ mv git-repo4/.git/objects/$COMMIT_OBJ.tmp git-repo4/.git/objects/$COMMIT_OBJ |
|
22 |
- damage git repository by renaming a blob object |
|
23 |
- |
|
24 |
-@@ -746,3 +746,21 @@ test for escaping the repo name (CVE-2016-3069) |
|
25 |
- updating bookmarks |
|
26 |
- $ test -f COMMAND-INJECTION |
|
27 |
- [1] |
|
28 |
-+ |
|
29 |
-+test for safely passing paths to git (CVE-2016-3105) |
|
30 |
-+ |
|
31 |
-+ $ git init 'ext::sh -c echo% pwned% >GIT-EXT-COMMAND-INJECTION% #' |
|
32 |
-+ Initialized empty Git repository in $TESTTMP/ext::sh -c echo% pwned% >GIT-EXT-COMMAND-INJECTION% #/.git/ |
|
33 |
-+ $ cd 'ext::sh -c echo% pwned% >GIT-EXT-COMMAND-INJECTION% #' |
|
34 |
-+ $ git commit -q --allow-empty -m 'empty' |
|
35 |
-+ $ cd .. |
|
36 |
-+ $ hg convert 'ext::sh -c echo% pwned% >GIT-EXT-COMMAND-INJECTION% #' 'converted-git-ext' |
|
37 |
-+ initializing destination converted-git-ext repository |
|
38 |
-+ scanning source... |
|
39 |
-+ sorting... |
|
40 |
-+ converting... |
|
41 |
-+ 0 empty |
|
42 |
-+ updating bookmarks |
|
43 |
-+ $ test -f GIT-EXT-COMMAND-INJECTION |
|
44 |
-+ [1] |
|
45 |
-+ |
|
46 |
- |
|
47 |
- |
|
48 |
-+++ b/tests/test-convert.t Wed Apr 06 22:57:46 2016 -0500 |
|
49 |
-@@ -422,7 +422,7 @@ |
|
50 |
- assuming destination emptydir-hg |
|
51 |
- initializing destination emptydir-hg repository |
|
52 |
- emptydir does not look like a CVS checkout |
|
53 |
-- emptydir does not look like a Git repository |
|
54 |
-+ $TESTTMP/emptydir does not look like a Git repository |
|
55 |
- emptydir does not look like a Subversion repository |
|
56 |
- emptydir is not a local Mercurial repository |
|
57 |
- emptydir does not look like a darcs repository |
|
58 |
- |
|
59 |
- |
60 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,96 +0,0 @@ |
1 |
- |
|
2 |
-+++ b/contrib/hg-ssh Wed Apr 12 11:23:55 2017 -0700 |
|
3 |
-@@ -32,7 +32,7 @@ command="hg-ssh --read-only repos/*" |
|
4 |
- # enable importing on demand to reduce startup time |
|
5 |
- from mercurial import demandimport; demandimport.enable() |
|
6 |
- |
|
7 |
--from mercurial import dispatch |
|
8 |
-+from mercurial import dispatch, ui as uimod |
|
9 |
- |
|
10 |
- import sys, os, shlex |
|
11 |
- |
|
12 |
-@@ -61,14 +61,15 @@ def main(): |
|
13 |
- repo = os.path.normpath(os.path.join(cwd, os.path.expanduser(path))) |
|
14 |
- if repo in allowed_paths: |
|
15 |
- cmd = ['-R', repo, 'serve', '--stdio'] |
|
16 |
-+ req = dispatch.request(cmd) |
|
17 |
- if readonly: |
|
18 |
-- cmd += [ |
|
19 |
-- '--config', |
|
20 |
-- 'hooks.pretxnopen.hg-ssh=python:__main__.rejectpush', |
|
21 |
-- '--config', |
|
22 |
-- 'hooks.prepushkey.hg-ssh=python:__main__.rejectpush' |
|
23 |
-- ] |
|
24 |
-- dispatch.dispatch(dispatch.request(cmd)) |
|
25 |
-+ if not req.ui: |
|
26 |
-+ req.ui = uimod.ui.load() |
|
27 |
-+ req.ui.setconfig('hooks', 'pretxnopen.hg-ssh', |
|
28 |
-+ 'python:__main__.rejectpush', 'hg-ssh') |
|
29 |
-+ req.ui.setconfig('hooks', 'prepushkey.hg-ssh', |
|
30 |
-+ 'python:__main__.rejectpush', 'hg-ssh') |
|
31 |
-+ dispatch.dispatch(req) |
|
32 |
- else: |
|
33 |
- sys.stderr.write('Illegal repository "%s"\n' % repo) |
|
34 |
- sys.exit(255) |
|
35 |
-+++ b/mercurial/dispatch.py Wed Apr 12 11:23:55 2017 -0700 |
|
36 |
-@@ -155,6 +155,37 @@ def _runcatch(req): |
|
37 |
- pass # happens if called in a thread |
|
38 |
- |
|
39 |
- def _runcatchfunc(): |
|
40 |
-+ realcmd = None |
|
41 |
-+ try: |
|
42 |
-+ cmdargs = fancyopts.fancyopts(req.args[:], commands.globalopts, {}) |
|
43 |
-+ cmd = cmdargs[0] |
|
44 |
-+ aliases, entry = cmdutil.findcmd(cmd, commands.table, False) |
|
45 |
-+ realcmd = aliases[0] |
|
46 |
-+ except (error.UnknownCommand, error.AmbiguousCommand, |
|
47 |
-+ IndexError, getopt.GetoptError): |
|
48 |
-+ # Don't handle this here. We know the command is |
|
49 |
-+ # invalid, but all we're worried about for now is that |
|
50 |
-+ # it's not a command that server operators expect to |
|
51 |
-+ # be safe to offer to users in a sandbox. |
|
52 |
-+ pass |
|
53 |
-+ if realcmd == 'serve' and '--stdio' in cmdargs: |
|
54 |
-+ # We want to constrain 'hg serve --stdio' instances pretty |
|
55 |
-+ # closely, as many shared-ssh access tools want to grant |
|
56 |
-+ # access to run *only* 'hg -R $repo serve --stdio'. We |
|
57 |
-+ # restrict to exactly that set of arguments, and prohibit |
|
58 |
-+ # any repo name that starts with '--' to prevent |
|
59 |
-+ # shenanigans wherein a user does something like pass |
|
60 |
-+ # --debugger or --config=ui.debugger=1 as a repo |
|
61 |
-+ # name. This used to actually run the debugger. |
|
62 |
-+ if (len(req.args) != 4 or |
|
63 |
-+ req.args[0] != '-R' or |
|
64 |
-+ req.args[1].startswith('--') or |
|
65 |
-+ req.args[2] != 'serve' or |
|
66 |
-+ req.args[3] != '--stdio'): |
|
67 |
-+ raise error.Abort( |
|
68 |
-+ _('potentially unsafe serve --stdio invocation: %r') % |
|
69 |
-+ (req.args,)) |
|
70 |
-+ |
|
71 |
- try: |
|
72 |
- debugger = 'pdb' |
|
73 |
- debugtrace = { |
|
74 |
-+++ b/tests/test-ssh.t Wed Apr 12 11:23:55 2017 -0700 |
|
75 |
-@@ -356,6 +356,18 @@ Test (non-)escaping of remote paths with spaces when cloning (issue3145): |
|
76 |
- destination directory: a repo |
|
77 |
- abort: destination 'a repo' is not empty |
|
78 |
- [255] |
|
79 |
-+Make sure hg is really paranoid in serve --stdio mode. It used to be |
|
80 |
-+possible to get a debugger REPL by specifying a repo named --debugger. |
|
81 |
-+ $ hg -R --debugger serve --stdio |
|
82 |
-+ abort: potentially unsafe serve --stdio invocation: ['-R', '--debugger', 'serve', '--stdio'] |
|
83 |
-+ [255] |
|
84 |
-+ $ hg -R --config=ui.debugger=yes serve --stdio |
|
85 |
-+ abort: potentially unsafe serve --stdio invocation: ['-R', '--config=ui.debugger=yes', 'serve', '--stdio'] |
|
86 |
-+ [255] |
|
87 |
-+Abbreviations of 'serve' also don't work, to avoid shenanigans. |
|
88 |
-+ $ hg -R narf serv --stdio |
|
89 |
-+ abort: potentially unsafe serve --stdio invocation: ['-R', 'narf', 'serv', '--stdio'] |
|
90 |
-+ [255] |
|
91 |
- |
|
92 |
- Test hg-ssh using a helper script that will restore PYTHONPATH (which might |
|
93 |
- have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right |
... | ... |
@@ -1,21 +1,20 @@ |
1 | 1 |
%{!?python2_sitelib: %global python2_sitelib %(python2 -c "from distutils.sysconfig import get_python_lib;print(get_python_lib())")} |
2 | 2 |
|
3 |
-Summary: A free, distributed source control management tool. |
|
4 |
-Name: mercurial |
|
5 |
-Version: 4.1 |
|
6 |
-Release: 4%{?dist} |
|
7 |
-License: GPLv2+ |
|
8 |
-URL: https://www.ruby-lang.org/en/ |
|
9 |
-Group: System Environment/Security |
|
10 |
-Vendor: VMware, Inc. |
|
11 |
-Distribution: Photon |
|
12 |
-Source0: http://mercurial.selenic.com/release/%{name}-%{version}.tar.gz |
|
13 |
-%define sha1 mercurial=d5f88e05cbbd8f13dd5fc4004433f54435fc27c8 |
|
14 |
-Patch0: hg-CVE-2017-9462.patch |
|
15 |
-BuildRequires: python2 |
|
16 |
-BuildRequires: python2-libs |
|
17 |
-BuildRequires: python2-devel |
|
18 |
-Requires: python2 |
|
3 |
+Summary: A free, distributed source control management tool. |
|
4 |
+Name: mercurial |
|
5 |
+Version: 4.3.3 |
|
6 |
+Release: 1%{?dist} |
|
7 |
+License: GPLv2+ |
|
8 |
+URL: https://www.mercurial-scm.org |
|
9 |
+Group: System Environment/Security |
|
10 |
+Vendor: VMware, Inc. |
|
11 |
+Distribution: Photon |
|
12 |
+Source0: https://www.mercurial-scm.org/release/%{name}-%{version}.tar.gz |
|
13 |
+%define sha1 mercurial=921c3c6302c4b1d4be6a56fcfa0a41553dd4bd44 |
|
14 |
+BuildRequires: python2 |
|
15 |
+BuildRequires: python2-libs |
|
16 |
+BuildRequires: python2-devel |
|
17 |
+Requires: python2 |
|
19 | 18 |
|
20 | 19 |
%description |
21 | 20 |
Mercurial is a distributed source control management tool similar to Git and Bazaar. |
... | ... |
@@ -23,7 +22,6 @@ Mercurial is written in Python and is used by projects such as Mozilla and Vim. |
23 | 23 |
|
24 | 24 |
%prep |
25 | 25 |
%setup -q |
26 |
-%patch0 -p1 |
|
27 | 26 |
|
28 | 27 |
%build |
29 | 28 |
make build |
... | ... |
@@ -59,6 +57,8 @@ rm -rf %{buildroot}/* |
59 | 59 |
%{python2_sitelib}/* |
60 | 60 |
|
61 | 61 |
%changelog |
62 |
+* Tue Oct 17 2017 Xiaolin Li <xiaolinl@vmware.com> 4.3.3-1 |
|
63 |
+- Update verion to 4.3.3 for CVE-2017-1000115, CVE-2017-1000116. |
|
62 | 64 |
* Fri Aug 11 2017 Rongrong Qiu <rqiu@vmware.com> 4.1-4 |
63 | 65 |
- update error info in make check for bug 1900338 |
64 | 66 |
* Fri Jun 16 2017 Dheeraj Shetty <dheerajs@vmware.com> 4.1-3 |