Change-Id: Ib0678d5623115d2b0e32104eea0293a8fabcb45b
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/1742
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Sharath George
1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,53 @@ |
0 |
+--- a/mercurial/subrepo.py Wed Mar 16 17:30:26 2016 -0700 |
|
1 |
+@@ -1383,6 +1383,11 @@ |
|
2 |
+ are not supported and very probably fail. |
|
3 |
+ """ |
|
4 |
+ self.ui.debug('%s: git %s\n' % (self._relpath, ' '.join(commands))) |
|
5 |
++ if env is None: |
|
6 |
++ env = os.environ.copy() |
|
7 |
++ # fix for Git CVE-2015-7545 |
|
8 |
++ if 'GIT_ALLOW_PROTOCOL' not in env: |
|
9 |
++ env['GIT_ALLOW_PROTOCOL'] = 'file:git:http:https:ssh' |
|
10 |
+ # unless ui.quiet is set, print git's stderr, |
|
11 |
+ # which is mostly progress and useful info |
|
12 |
+ errpipe = None |
|
13 |
+--- a/tests/test-subrepo-git.t Wed Mar 16 17:30:26 2016 -0700 |
|
14 |
+@@ -1132,4 +1132,36 @@ |
|
15 |
+ ? s/foobar.orig |
|
16 |
+ ? s/snake.python.orig |
|
17 |
+ |
|
18 |
++test for Git CVE-2016-3068 |
|
19 |
++ $ hg init malicious-subrepository |
|
20 |
++ $ cd malicious-subrepository |
|
21 |
++ $ echo "s = [git]ext::sh -c echo% pwned% >&2" > .hgsub |
|
22 |
++ $ git init s |
|
23 |
++ Initialized empty Git repository in $TESTTMP/tc/malicious-subrepository/s/.git/ |
|
24 |
++ $ cd s |
|
25 |
++ $ git commit --allow-empty -m 'empty' |
|
26 |
++ [master (root-commit) 153f934] empty |
|
27 |
+ $ cd .. |
|
28 |
++ $ hg add .hgsub |
|
29 |
++ $ hg commit -m "add subrepo" |
|
30 |
++ $ cd .. |
|
31 |
++ $ env -u GIT_ALLOW_PROTOCOL hg clone malicious-subrepository malicious-subrepository-protected |
|
32 |
++ Cloning into '$TESTTMP/tc/malicious-subrepository-protected/s'... |
|
33 |
++ fatal: transport 'ext' not allowed |
|
34 |
++ updating to branch default |
|
35 |
++ cloning subrepo s from ext::sh -c echo% pwned% >&2 |
|
36 |
++ abort: git clone error 128 in s (in subrepo s) |
|
37 |
++ [255] |
|
38 |
++ |
|
39 |
++whitelisting of ext should be respected (that's the git submodule behaviour) |
|
40 |
++ $ env GIT_ALLOW_PROTOCOL=ext hg clone malicious-subrepository malicious-subrepository-clone-allowed |
|
41 |
++ Cloning into '$TESTTMP/tc/malicious-subrepository-clone-allowed/s'... |
|
42 |
++ pwned |
|
43 |
++ fatal: Could not read from remote repository. |
|
44 |
++ |
|
45 |
++ Please make sure you have the correct access rights |
|
46 |
++ and the repository exists. |
|
47 |
++ updating to branch default |
|
48 |
++ cloning subrepo s from ext::sh -c echo% pwned% >&2 |
|
49 |
++ abort: git clone error 128 in s (in subrepo s) |
|
50 |
++ [255] |
0 | 51 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,50 @@ |
0 |
+--- a/hgext/convert/git.py Sun Mar 20 21:52:21 2016 -0700 |
|
1 |
+@@ -11,7 +11,7 @@ |
|
2 |
+ from mercurial.node import hex, nullid |
|
3 |
+ from mercurial.i18n import _ |
|
4 |
+ |
|
5 |
+-from common import NoRepo, commit, converter_source, checktool |
|
6 |
++from common import NoRepo, commit, converter_source, checktool, commandline |
|
7 |
+ |
|
8 |
+ class submodule(object): |
|
9 |
+ def __init__(self, path, node, url): |
|
10 |
+@@ -25,7 +25,7 @@ |
|
11 |
+ def hgsubstate(self): |
|
12 |
+ return "%s %s" % (self.node, self.path) |
|
13 |
+ |
|
14 |
+-class convert_git(converter_source): |
|
15 |
++class convert_git(converter_source, commandline): |
|
16 |
+ # Windows does not support GIT_DIR= construct while other systems |
|
17 |
+ # cannot remove environment variable. Just assume none have |
|
18 |
+ # both issues. |
|
19 |
+@@ -71,6 +71,21 @@ |
|
20 |
+ def gitpipe(self, s): |
|
21 |
+ return util.popen3('GIT_DIR=%s %s' % (self.path, s)) |
|
22 |
+ |
|
23 |
++ def _gitcmd(self, cmd, *args, **kwargs): |
|
24 |
++ return cmd('--git-dir=%s' % self.path, *args, **kwargs) |
|
25 |
++ |
|
26 |
++ def gitrun0(self, *args, **kwargs): |
|
27 |
++ return self._gitcmd(self.run0, *args, **kwargs) |
|
28 |
++ |
|
29 |
++ def gitrun(self, *args, **kwargs): |
|
30 |
++ return self._gitcmd(self.run, *args, **kwargs) |
|
31 |
++ |
|
32 |
++ def gitrunlines0(self, *args, **kwargs): |
|
33 |
++ return self._gitcmd(self.runlines0, *args, **kwargs) |
|
34 |
++ |
|
35 |
++ def gitrunlines(self, *args, **kwargs): |
|
36 |
++ return self._gitcmd(self.runlines, *args, **kwargs) |
|
37 |
++ |
|
38 |
+ def popen_with_stderr(self, s): |
|
39 |
+ p = subprocess.Popen(s, shell=True, bufsize=-1, |
|
40 |
+ close_fds=util.closefds, |
|
41 |
+@@ -88,6 +103,7 @@ |
|
42 |
+ |
|
43 |
+ def __init__(self, ui, path, revs=None): |
|
44 |
+ super(convert_git, self).__init__(ui, path, revs=revs) |
|
45 |
++ commandline.__init__(self, ui, 'git') |
|
46 |
+ |
|
47 |
+ if os.path.isdir(path + "/.git"): |
|
48 |
+ path += "/.git" |
0 | 49 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,173 @@ |
0 |
+--- a/hgext/convert/git.py Tue Mar 22 17:05:11 2016 -0700 |
|
1 |
+@@ -115,13 +115,13 @@ |
|
2 |
+ if similarity < 0 or similarity > 100: |
|
3 |
+ raise error.Abort(_('similarity must be between 0 and 100')) |
|
4 |
+ if similarity > 0: |
|
5 |
+- self.simopt = '-C%d%%' % similarity |
|
6 |
++ self.simopt = ['-C%d%%' % similarity] |
|
7 |
+ findcopiesharder = ui.configbool('convert', 'git.findcopiesharder', |
|
8 |
+ False) |
|
9 |
+ if findcopiesharder: |
|
10 |
+- self.simopt += ' --find-copies-harder' |
|
11 |
++ self.simopt.append('--find-copies-harder') |
|
12 |
+ else: |
|
13 |
+- self.simopt = '' |
|
14 |
++ self.simopt = [] |
|
15 |
+ |
|
16 |
+ checktool('git', 'git') |
|
17 |
+ |
|
18 |
+@@ -136,14 +136,14 @@ |
|
19 |
+ |
|
20 |
+ def getheads(self): |
|
21 |
+ if not self.revs: |
|
22 |
+- heads, ret = self.gitread('git rev-parse --branches --remotes') |
|
23 |
+- heads = heads.splitlines() |
|
24 |
+- if ret: |
|
25 |
++ output, status = self.gitrun('rev-parse', '--branches', '--remotes') |
|
26 |
++ heads = output.splitlines() |
|
27 |
++ if status: |
|
28 |
+ raise error.Abort(_('cannot retrieve git heads')) |
|
29 |
+ else: |
|
30 |
+ heads = [] |
|
31 |
+ for rev in self.revs: |
|
32 |
+- rawhead, ret = self.gitread("git rev-parse --verify %s" % rev) |
|
33 |
++ rawhead, ret = self.gitrun('rev-parse', '--verify', rev) |
|
34 |
+ heads.append(rawhead[:-1]) |
|
35 |
+ if ret: |
|
36 |
+ raise error.Abort(_('cannot retrieve git head "%s"') % rev) |
|
37 |
+@@ -203,7 +203,7 @@ |
|
38 |
+ self.submodules.append(submodule(s['path'], '', s['url'])) |
|
39 |
+ |
|
40 |
+ def retrievegitmodules(self, version): |
|
41 |
+- modules, ret = self.gitread("git show %s:%s" % (version, '.gitmodules')) |
|
42 |
++ modules, ret = self.gitrun('show', '%s:%s' % (version, '.gitmodules')) |
|
43 |
+ if ret: |
|
44 |
+ # This can happen if a file is in the repo that has permissions |
|
45 |
+ # 160000, but there is no .gitmodules file. |
|
46 |
+@@ -219,7 +219,7 @@ |
|
47 |
+ return |
|
48 |
+ |
|
49 |
+ for m in self.submodules: |
|
50 |
+- node, ret = self.gitread("git rev-parse %s:%s" % (version, m.path)) |
|
51 |
++ node, ret = self.gitrun('rev-parse', '%s:%s' % (version, m.path)) |
|
52 |
+ if ret: |
|
53 |
+ continue |
|
54 |
+ m.node = node.strip() |
|
55 |
+@@ -228,15 +228,17 @@ |
|
56 |
+ if full: |
|
57 |
+ raise error.Abort(_("convert from git does not support --full")) |
|
58 |
+ self.modecache = {} |
|
59 |
+- fh = self.gitopen("git diff-tree -z --root -m -r %s %s" % ( |
|
60 |
+- self.simopt, version)) |
|
61 |
++ cmd = ['diff-tree','-z', '--root', '-m', '-r'] + self.simopt + [version] |
|
62 |
++ output, status = self.gitrun(*cmd) |
|
63 |
++ if status: |
|
64 |
++ raise error.Abort(_('cannot read changes in %s') % version) |
|
65 |
+ changes = [] |
|
66 |
+ copies = {} |
|
67 |
+ seen = set() |
|
68 |
+ entry = None |
|
69 |
+ subexists = [False] |
|
70 |
+ subdeleted = [False] |
|
71 |
+- difftree = fh.read().split('\x00') |
|
72 |
++ difftree = output.split('\x00') |
|
73 |
+ lcount = len(difftree) |
|
74 |
+ i = 0 |
|
75 |
+ |
|
76 |
+@@ -298,8 +300,6 @@ |
|
77 |
+ if f != '.gitmodules' and fdest != '.gitmodules': |
|
78 |
+ copies[fdest] = f |
|
79 |
+ entry = None |
|
80 |
+- if fh.close(): |
|
81 |
+- raise error.Abort(_('cannot read changes in %s') % version) |
|
82 |
+ |
|
83 |
+ if subexists[0]: |
|
84 |
+ if subdeleted[0]: |
|
85 |
+@@ -345,17 +345,23 @@ |
|
86 |
+ return c |
|
87 |
+ |
|
88 |
+ def numcommits(self): |
|
89 |
+- return len([None for _ in self.gitopen('git rev-list --all')]) |
|
90 |
++ output, ret = self.gitrunlines('rev-list', '--all') |
|
91 |
++ if ret: |
|
92 |
++ raise error.Abort(_('cannot retrieve number of commits in %s') \ |
|
93 |
++ % self.path) |
|
94 |
++ return len(output) |
|
95 |
+ |
|
96 |
+ def gettags(self): |
|
97 |
+ tags = {} |
|
98 |
+ alltags = {} |
|
99 |
+- fh = self.gitopen('git ls-remote --tags "%s"' % self.path, |
|
100 |
+- err=subprocess.STDOUT) |
|
101 |
++ output, status = self.gitrunlines('ls-remote', '--tags', self.path) |
|
102 |
++ |
|
103 |
++ if status: |
|
104 |
++ raise error.Abort(_('cannot read tags from %s') % self.path) |
|
105 |
+ prefix = 'refs/tags/' |
|
106 |
+ |
|
107 |
+ # Build complete list of tags, both annotated and bare ones |
|
108 |
+- for line in fh: |
|
109 |
++ for line in output: |
|
110 |
+ line = line.strip() |
|
111 |
+ if line.startswith("error:") or line.startswith("fatal:"): |
|
112 |
+ raise error.Abort(_('cannot read tags from %s') % self.path) |
|
113 |
+@@ -363,8 +369,6 @@ |
|
114 |
+ if not tag.startswith(prefix): |
|
115 |
+ continue |
|
116 |
+ alltags[tag[len(prefix):]] = node |
|
117 |
+- if fh.close(): |
|
118 |
+- raise error.Abort(_('cannot read tags from %s') % self.path) |
|
119 |
+ |
|
120 |
+ # Filter out tag objects for annotated tag refs |
|
121 |
+ for tag in alltags: |
|
122 |
+@@ -381,18 +385,20 @@ |
|
123 |
+ def getchangedfiles(self, version, i): |
|
124 |
+ changes = [] |
|
125 |
+ if i is None: |
|
126 |
+- fh = self.gitopen("git diff-tree --root -m -r %s" % version) |
|
127 |
+- for l in fh: |
|
128 |
++ output, status = self.gitrunlines('diff-tree', '--root', '-m', |
|
129 |
++ '-r', version) |
|
130 |
++ if status: |
|
131 |
++ raise error.Abort(_('cannot read changes in %s') % version) |
|
132 |
++ for l in output: |
|
133 |
+ if "\t" not in l: |
|
134 |
+ continue |
|
135 |
+ m, f = l[:-1].split("\t") |
|
136 |
+ changes.append(f) |
|
137 |
+ else: |
|
138 |
+- fh = self.gitopen('git diff-tree --name-only --root -r %s ' |
|
139 |
+- '"%s^%s" --' % (version, version, i + 1)) |
|
140 |
+- changes = [f.rstrip('\n') for f in fh] |
|
141 |
+- if fh.close(): |
|
142 |
+- raise error.Abort(_('cannot read changes in %s') % version) |
|
143 |
++ output, status = self.gitrunlines('diff-tree', '--name-only', |
|
144 |
++ '--root', '-r', version, |
|
145 |
++ '%s^%s' % (version, i + 1), '--') |
|
146 |
++ changes = [f.rstrip('\n') for f in output] |
|
147 |
+ |
|
148 |
+ return changes |
|
149 |
+ |
|
150 |
+@@ -412,8 +418,8 @@ |
|
151 |
+ ]) |
|
152 |
+ |
|
153 |
+ try: |
|
154 |
+- fh = self.gitopen('git show-ref', err=subprocess.PIPE) |
|
155 |
+- for line in fh: |
|
156 |
++ output, status = self.gitrunlines('show-ref') |
|
157 |
++ for line in output: |
|
158 |
+ line = line.strip() |
|
159 |
+ rev, name = line.split(None, 1) |
|
160 |
+ # Process each type of branch |
|
161 |
+--- a/tests/test-convert-git.t Tue Mar 22 17:05:11 2016 -0700 |
|
162 |
+@@ -714,7 +714,7 @@ |
|
163 |
+ $ COMMIT_OBJ=1c/0ce3c5886f83a1d78a7b517cdff5cf9ca17bdd |
|
164 |
+ $ mv git-repo4/.git/objects/$COMMIT_OBJ git-repo4/.git/objects/$COMMIT_OBJ.tmp |
|
165 |
+ $ hg convert git-repo4 git-repo4-broken-hg 2>&1 | grep 'abort:' |
|
166 |
+- abort: cannot read tags from git-repo4/.git |
|
167 |
++ abort: cannot retrieve number of commits in git-repo4/.git |
|
168 |
+ $ mv git-repo4/.git/objects/$COMMIT_OBJ.tmp git-repo4/.git/objects/$COMMIT_OBJ |
|
169 |
+ damage git repository by renaming a blob object |
|
170 |
+ |
0 | 171 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,59 @@ |
0 |
+--- a/hgext/convert/git.py Tue Mar 22 17:05:11 2016 -0700 |
|
1 |
+@@ -30,23 +30,6 @@ |
|
2 |
+ # cannot remove environment variable. Just assume none have |
|
3 |
+ # both issues. |
|
4 |
+ if util.safehasattr(os, 'unsetenv'): |
|
5 |
+- def gitopen(self, s, err=None): |
|
6 |
+- prevgitdir = os.environ.get('GIT_DIR') |
|
7 |
+- os.environ['GIT_DIR'] = self.path |
|
8 |
+- try: |
|
9 |
+- if err == subprocess.PIPE: |
|
10 |
+- (stdin, stdout, stderr) = util.popen3(s) |
|
11 |
+- return stdout |
|
12 |
+- elif err == subprocess.STDOUT: |
|
13 |
+- return self.popen_with_stderr(s) |
|
14 |
+- else: |
|
15 |
+- return util.popen(s, 'rb') |
|
16 |
+- finally: |
|
17 |
+- if prevgitdir is None: |
|
18 |
+- del os.environ['GIT_DIR'] |
|
19 |
+- else: |
|
20 |
+- os.environ['GIT_DIR'] = prevgitdir |
|
21 |
+- |
|
22 |
+ def gitpipe(self, s): |
|
23 |
+ prevgitdir = os.environ.get('GIT_DIR') |
|
24 |
+ os.environ['GIT_DIR'] = self.path |
|
25 |
+@@ -59,15 +42,6 @@ |
|
26 |
+ os.environ['GIT_DIR'] = prevgitdir |
|
27 |
+ |
|
28 |
+ else: |
|
29 |
+- def gitopen(self, s, err=None): |
|
30 |
+- if err == subprocess.PIPE: |
|
31 |
+- (sin, so, se) = util.popen3('GIT_DIR=%s %s' % (self.path, s)) |
|
32 |
+- return so |
|
33 |
+- elif err == subprocess.STDOUT: |
|
34 |
+- return self.popen_with_stderr(s) |
|
35 |
+- else: |
|
36 |
+- return util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb') |
|
37 |
+- |
|
38 |
+ def gitpipe(self, s): |
|
39 |
+ return util.popen3('GIT_DIR=%s %s' % (self.path, s)) |
|
40 |
+ |
|
41 |
+@@ -86,16 +60,6 @@ |
|
42 |
+ def gitrunlines(self, *args, **kwargs): |
|
43 |
+ return self._gitcmd(self.runlines, *args, **kwargs) |
|
44 |
+ |
|
45 |
+- def popen_with_stderr(self, s): |
|
46 |
+- p = subprocess.Popen(s, shell=True, bufsize=-1, |
|
47 |
+- close_fds=util.closefds, |
|
48 |
+- stdin=subprocess.PIPE, |
|
49 |
+- stdout=subprocess.PIPE, |
|
50 |
+- stderr=subprocess.STDOUT, |
|
51 |
+- universal_newlines=False, |
|
52 |
+- env=None) |
|
53 |
+- return p.stdout |
|
54 |
+- |
|
55 |
+ def gitread(self, s): |
|
56 |
+ fh = self.gitopen(s) |
|
57 |
+ data = fh.read() |
0 | 58 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,55 @@ |
0 |
+--- a/hgext/convert/common.py Tue Mar 22 17:05:11 2016 -0700 |
|
1 |
+@@ -341,6 +341,9 @@ |
|
2 |
+ def _run2(self, cmd, *args, **kwargs): |
|
3 |
+ return self._dorun(util.popen2, cmd, *args, **kwargs) |
|
4 |
+ |
|
5 |
++ def _run3(self, cmd, *args, **kwargs): |
|
6 |
++ return self._dorun(util.popen3, cmd, *args, **kwargs) |
|
7 |
++ |
|
8 |
+ def _dorun(self, openfunc, cmd, *args, **kwargs): |
|
9 |
+ cmdline = self._cmdline(cmd, *args, **kwargs) |
|
10 |
+ self.ui.debug('running: %s\n' % (cmdline,)) |
|
11 |
+--- a/hgext/convert/git.py Tue Mar 22 17:05:11 2016 -0700 |
|
12 |
+@@ -29,21 +29,6 @@ |
|
13 |
+ # Windows does not support GIT_DIR= construct while other systems |
|
14 |
+ # cannot remove environment variable. Just assume none have |
|
15 |
+ # both issues. |
|
16 |
+- if util.safehasattr(os, 'unsetenv'): |
|
17 |
+- def gitpipe(self, s): |
|
18 |
+- prevgitdir = os.environ.get('GIT_DIR') |
|
19 |
+- os.environ['GIT_DIR'] = self.path |
|
20 |
+- try: |
|
21 |
+- return util.popen3(s) |
|
22 |
+- finally: |
|
23 |
+- if prevgitdir is None: |
|
24 |
+- del os.environ['GIT_DIR'] |
|
25 |
+- else: |
|
26 |
+- os.environ['GIT_DIR'] = prevgitdir |
|
27 |
+- |
|
28 |
+- else: |
|
29 |
+- def gitpipe(self, s): |
|
30 |
+- return util.popen3('GIT_DIR=%s %s' % (self.path, s)) |
|
31 |
+ |
|
32 |
+ def _gitcmd(self, cmd, *args, **kwargs): |
|
33 |
+ return cmd('--git-dir=%s' % self.path, *args, **kwargs) |
|
34 |
+@@ -60,6 +45,9 @@ |
|
35 |
+ def gitrunlines(self, *args, **kwargs): |
|
36 |
+ return self._gitcmd(self.runlines, *args, **kwargs) |
|
37 |
+ |
|
38 |
++ def gitpipe(self, *args, **kwargs): |
|
39 |
++ return self._gitcmd(self._run3, *args, **kwargs) |
|
40 |
++ |
|
41 |
+ def gitread(self, s): |
|
42 |
+ fh = self.gitopen(s) |
|
43 |
+ data = fh.read() |
|
44 |
+@@ -92,7 +80,7 @@ |
|
45 |
+ self.path = path |
|
46 |
+ self.submodules = [] |
|
47 |
+ |
|
48 |
+- self.catfilepipe = self.gitpipe('git cat-file --batch') |
|
49 |
++ self.catfilepipe = self.gitpipe('cat-file', '--batch') |
|
50 |
+ |
|
51 |
+ def after(self): |
|
52 |
+ for f in self.catfilepipe: |
0 | 53 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,23 @@ |
0 |
+--- a/tests/test-convert-git.t Tue Mar 22 17:05:11 2016 -0700 |
|
1 |
+@@ -729,3 +729,20 @@ |
|
2 |
+ $ mv git-repo4/.git/objects/$TREE_OBJ git-repo4/.git/objects/$TREE_OBJ.tmp |
|
3 |
+ $ hg convert git-repo4 git-repo4-broken-hg 2>&1 | grep 'abort:' |
|
4 |
+ abort: cannot read changes in 1c0ce3c5886f83a1d78a7b517cdff5cf9ca17bdd |
|
5 |
++ |
|
6 |
++test for escaping the repo name (CVE-2016-3069) |
|
7 |
++ |
|
8 |
++ $ git init '`echo pwned >COMMAND-INJECTION`' |
|
9 |
++ Initialized empty Git repository in $TESTTMP/`echo pwned >COMMAND-INJECTION`/.git/ |
|
10 |
++ $ cd '`echo pwned >COMMAND-INJECTION`' |
|
11 |
++ $ git commit -q --allow-empty -m 'empty' |
|
12 |
++ $ cd .. |
|
13 |
++ $ hg convert '`echo pwned >COMMAND-INJECTION`' 'converted' |
|
14 |
++ initializing destination converted repository |
|
15 |
++ scanning source... |
|
16 |
++ sorting... |
|
17 |
++ converting... |
|
18 |
++ 0 empty |
|
19 |
++ updating bookmarks |
|
20 |
++ $ test -f COMMAND-INJECTION |
|
21 |
++ [1] |
0 | 22 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,62 @@ |
0 |
+--- a/hgext/convert/git.py Sun May 01 13:52:26 2016 -0500 |
|
1 |
+@@ -57,6 +57,10 @@ class convert_git(converter_source, commandline): |
|
2 |
+ super(convert_git, self).__init__(ui, path, revs=revs) |
|
3 |
+ commandline.__init__(self, ui, 'git') |
|
4 |
+ |
|
5 |
++ # Pass an absolute path to git to prevent from ever being interpreted |
|
6 |
++ # as a URL |
|
7 |
++ path = os.path.abspath(path) |
|
8 |
++ |
|
9 |
+ if os.path.isdir(path + "/.git"): |
|
10 |
+ path += "/.git" |
|
11 |
+ if not os.path.exists(path + "/objects"): |
|
12 |
+ |
|
13 |
+--- a/tests/test-convert-git.t Sun May 01 13:52:26 2016 -0500 |
|
14 |
+@@ -714,7 +714,7 @@ |
|
15 |
+ $ COMMIT_OBJ=1c/0ce3c5886f83a1d78a7b517cdff5cf9ca17bdd |
|
16 |
+ $ mv git-repo4/.git/objects/$COMMIT_OBJ git-repo4/.git/objects/$COMMIT_OBJ.tmp |
|
17 |
+ $ hg convert git-repo4 git-repo4-broken-hg 2>&1 | grep 'abort:' |
|
18 |
+- abort: cannot retrieve number of commits in git-repo4/.git |
|
19 |
++ abort: cannot retrieve number of commits in $TESTTMP/git-repo4/.git |
|
20 |
+ $ mv git-repo4/.git/objects/$COMMIT_OBJ.tmp git-repo4/.git/objects/$COMMIT_OBJ |
|
21 |
+ damage git repository by renaming a blob object |
|
22 |
+ |
|
23 |
+@@ -746,3 +746,21 @@ test for escaping the repo name (CVE-2016-3069) |
|
24 |
+ updating bookmarks |
|
25 |
+ $ test -f COMMAND-INJECTION |
|
26 |
+ [1] |
|
27 |
++ |
|
28 |
++test for safely passing paths to git (CVE-2016-3105) |
|
29 |
++ |
|
30 |
++ $ git init 'ext::sh -c echo% pwned% >GIT-EXT-COMMAND-INJECTION% #' |
|
31 |
++ Initialized empty Git repository in $TESTTMP/ext::sh -c echo% pwned% >GIT-EXT-COMMAND-INJECTION% #/.git/ |
|
32 |
++ $ cd 'ext::sh -c echo% pwned% >GIT-EXT-COMMAND-INJECTION% #' |
|
33 |
++ $ git commit -q --allow-empty -m 'empty' |
|
34 |
++ $ cd .. |
|
35 |
++ $ hg convert 'ext::sh -c echo% pwned% >GIT-EXT-COMMAND-INJECTION% #' 'converted-git-ext' |
|
36 |
++ initializing destination converted-git-ext repository |
|
37 |
++ scanning source... |
|
38 |
++ sorting... |
|
39 |
++ converting... |
|
40 |
++ 0 empty |
|
41 |
++ updating bookmarks |
|
42 |
++ $ test -f GIT-EXT-COMMAND-INJECTION |
|
43 |
++ [1] |
|
44 |
++ |
|
45 |
+ |
|
46 |
+ |
|
47 |
+--- a/tests/test-convert.t Sun May 01 13:52:26 2016 -0500 |
|
48 |
+@@ -422,7 +422,7 @@ |
|
49 |
+ assuming destination emptydir-hg |
|
50 |
+ initializing destination emptydir-hg repository |
|
51 |
+ emptydir does not look like a CVS checkout |
|
52 |
+- emptydir does not look like a Git repository |
|
53 |
++ $TESTTMP/emptydir does not look like a Git repository |
|
54 |
+ emptydir does not look like a Subversion repository |
|
55 |
+ emptydir is not a local Mercurial repository |
|
56 |
+ emptydir does not look like a darcs repository |
|
57 |
+ |
|
58 |
+ |
... | ... |
@@ -1,23 +1,37 @@ |
1 |
-Summary: Mercurial-3.1.2 |
|
2 |
-Name: mercurial |
|
3 |
-Version: 3.7.1 |
|
4 |
-Release: 4%{?dist} |
|
5 |
-License: GPLv2+ |
|
6 |
-URL: https://www.ruby-lang.org/en/ |
|
7 |
-Group: System Environment/Security |
|
8 |
-Vendor: VMware, Inc. |
|
1 |
+Summary: A free, distributed source control management tool. |
|
2 |
+Name: mercurial |
|
3 |
+Version: 3.7.1 |
|
4 |
+Release: 5%{?dist} |
|
5 |
+License: GPLv2+ |
|
6 |
+URL: https://www.ruby-lang.org/en/ |
|
7 |
+Group: System Environment/Security |
|
8 |
+Vendor: VMware, Inc. |
|
9 | 9 |
Distribution: Photon |
10 |
-Source0: http://mercurial.selenic.com/release/%{name}-%{version}.tar.gz |
|
10 |
+Source0: http://mercurial.selenic.com/release/%{name}-%{version}.tar.gz |
|
11 | 11 |
%define sha1 mercurial=8ce55b297c6a62e987657498746eeca870301ffb |
12 |
-BuildRequires: python2-devel |
|
13 |
-BuildRequires: python2-libs |
|
14 |
-Requires: python2 |
|
12 |
+Patch0: hg-CVE-2016-3068.patch |
|
13 |
+Patch1: hg-CVE-2016-3069-1.patch |
|
14 |
+Patch2: hg-CVE-2016-3069-2.patch |
|
15 |
+Patch3: hg-CVE-2016-3069-3.patch |
|
16 |
+Patch4: hg-CVE-2016-3069-4.patch |
|
17 |
+Patch5: hg-CVE-2016-3069-5.patch |
|
18 |
+Patch6: hg-CVE-2016-3105.patch |
|
19 |
+BuildRequires: python2-devel |
|
20 |
+BuildRequires: python2-libs |
|
21 |
+Requires: python2 |
|
15 | 22 |
%description |
16 | 23 |
Mercurial is a distributed source control management tool similar to Git and Bazaar. |
17 | 24 |
Mercurial is written in Python and is used by projects such as Mozilla and Vim. |
18 | 25 |
|
19 | 26 |
%prep |
20 | 27 |
%setup -q |
28 |
+%patch0 -p1 |
|
29 |
+%patch1 -p1 |
|
30 |
+%patch2 -p1 |
|
31 |
+%patch3 -p1 |
|
32 |
+%patch4 -p1 |
|
33 |
+%patch5 -p1 |
|
34 |
+%patch6 -p1 |
|
21 | 35 |
%build |
22 | 36 |
make build |
23 | 37 |
%install |
... | ... |
@@ -63,19 +77,21 @@ rm -rf %{buildroot}/* |
63 | 63 |
%exclude /var/opt/%{name}-%{version}/contrib/plan9 |
64 | 64 |
%exclude /var/opt/%{name}-%{version}/build/temp.* |
65 | 65 |
%changelog |
66 |
-* Fri Oct 07 2016 ChangLee <changlee@vmware.com> 3.7.1-4 |
|
67 |
-- Modified %check |
|
68 |
-* Tue May 24 2016 Priyesh Padmavilasom <ppadmavilasom@vmware.com> 3.7.1-3 |
|
69 |
-- GA - Bump release of all rpms |
|
70 |
-* Wed May 04 2016 Anish Swaminathan <anishs@vmware.com> 3.7.1-2 |
|
71 |
-- Edit postun script. |
|
72 |
-* Thu Feb 25 2016 Kumar Kaushik <kaushikk@vmware.com> 3.7.1-1 |
|
73 |
-- Updating Version. |
|
74 |
-* Wed Dec 09 2015 Anish Swaminathan <anishs@vmware.com> 3.1.2-4 |
|
75 |
-- Edit post script. |
|
76 |
-* Mon Nov 16 2015 Sharath George <sharathg@vmware.com> 3.1.2-3 |
|
77 |
-- Change path to /var/opt. |
|
78 |
-* Tue Jun 30 2015 Alexey Makhalov <amakhalov@vmware.com> 3.1.2-2 |
|
79 |
-- /etc/profile.d permission fix |
|
80 |
-* Mon Oct 13 2014 Divya Thaluru <dthaluru@vmware.com> 3.1.2-1 |
|
81 |
-- Initial build. First version |
|
66 |
+* Tue Nov 22 2016 Xiaolin Li <xiaolinl@vmware.com> 3.7.1-5 |
|
67 |
+- Apply patches for CVE-2016-3068, CVE-2016-3069, CVE-2016-3105 |
|
68 |
+* Fri Oct 07 2016 ChangLee <changlee@vmware.com> 3.7.1-4 |
|
69 |
+- Modified %check |
|
70 |
+* Tue May 24 2016 Priyesh Padmavilasom <ppadmavilasom@vmware.com> 3.7.1-3 |
|
71 |
+- GA - Bump release of all rpms |
|
72 |
+* Wed May 04 2016 Anish Swaminathan <anishs@vmware.com> 3.7.1-2 |
|
73 |
+- Edit postun script. |
|
74 |
+* Thu Feb 25 2016 Kumar Kaushik <kaushikk@vmware.com> 3.7.1-1 |
|
75 |
+- Updating Version. |
|
76 |
+* Wed Dec 09 2015 Anish Swaminathan <anishs@vmware.com> 3.1.2-4 |
|
77 |
+- Edit post script. |
|
78 |
+* Mon Nov 16 2015 Sharath George <sharathg@vmware.com> 3.1.2-3 |
|
79 |
+- Change path to /var/opt. |
|
80 |
+* Tue Jun 30 2015 Alexey Makhalov <amakhalov@vmware.com> 3.1.2-2 |
|
81 |
+- /etc/profile.d permission fix |
|
82 |
+* Mon Oct 13 2014 Divya Thaluru <dthaluru@vmware.com> 3.1.2-1 |
|
83 |
+- Initial build. First version |