mirror of
https://github.com/facebook/sapling.git
synced 2024-10-08 07:49:11 +03:00
merge with stable
This commit is contained in:
commit
4a96519522
1
.hgsigs
1
.hgsigs
@ -122,3 +122,4 @@ ea389970c08449440587712117f178d33bab3f1e 0 iQIVAwUAVociGyBXgaxoKi1yAQJx9Q//TzMyp
|
||||
2408645de650d8a29a6ce9e7dce601d8dd0d1474 0 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
|
||||
|
@ -352,6 +352,9 @@ class commandline(object):
|
||||
def _run2(self, cmd, *args, **kwargs):
|
||||
return self._dorun(util.popen2, cmd, *args, **kwargs)
|
||||
|
||||
def _run3(self, cmd, *args, **kwargs):
|
||||
return self._dorun(util.popen3, cmd, *args, **kwargs)
|
||||
|
||||
def _dorun(self, openfunc, cmd, *args, **kwargs):
|
||||
cmdline = self._cmdline(cmd, *args, **kwargs)
|
||||
self.ui.debug('running: %s\n' % (cmdline,))
|
||||
|
@ -32,61 +32,28 @@ class submodule(object):
|
||||
def hgsubstate(self):
|
||||
return "%s %s" % (self.node, self.path)
|
||||
|
||||
class convert_git(common.converter_source):
|
||||
class convert_git(common.converter_source, common.commandline):
|
||||
# Windows does not support GIT_DIR= construct while other systems
|
||||
# cannot remove environment variable. Just assume none have
|
||||
# both issues.
|
||||
if util.safehasattr(os, 'unsetenv'):
|
||||
def gitopen(self, s, err=None):
|
||||
prevgitdir = os.environ.get('GIT_DIR')
|
||||
os.environ['GIT_DIR'] = self.path
|
||||
try:
|
||||
if err == subprocess.PIPE:
|
||||
(stdin, stdout, stderr) = util.popen3(s)
|
||||
return stdout
|
||||
elif err == subprocess.STDOUT:
|
||||
return self.popen_with_stderr(s)
|
||||
else:
|
||||
return util.popen(s, 'rb')
|
||||
finally:
|
||||
if prevgitdir is None:
|
||||
del os.environ['GIT_DIR']
|
||||
else:
|
||||
os.environ['GIT_DIR'] = prevgitdir
|
||||
|
||||
def gitpipe(self, s):
|
||||
prevgitdir = os.environ.get('GIT_DIR')
|
||||
os.environ['GIT_DIR'] = self.path
|
||||
try:
|
||||
return util.popen3(s)
|
||||
finally:
|
||||
if prevgitdir is None:
|
||||
del os.environ['GIT_DIR']
|
||||
else:
|
||||
os.environ['GIT_DIR'] = prevgitdir
|
||||
def _gitcmd(self, cmd, *args, **kwargs):
|
||||
return cmd('--git-dir=%s' % self.path, *args, **kwargs)
|
||||
|
||||
else:
|
||||
def gitopen(self, s, err=None):
|
||||
if err == subprocess.PIPE:
|
||||
(sin, so, se) = util.popen3('GIT_DIR=%s %s' % (self.path, s))
|
||||
return so
|
||||
elif err == subprocess.STDOUT:
|
||||
return self.popen_with_stderr(s)
|
||||
else:
|
||||
return util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb')
|
||||
def gitrun0(self, *args, **kwargs):
|
||||
return self._gitcmd(self.run0, *args, **kwargs)
|
||||
|
||||
def gitpipe(self, s):
|
||||
return util.popen3('GIT_DIR=%s %s' % (self.path, s))
|
||||
def gitrun(self, *args, **kwargs):
|
||||
return self._gitcmd(self.run, *args, **kwargs)
|
||||
|
||||
def popen_with_stderr(self, s):
|
||||
p = subprocess.Popen(s, shell=True, bufsize=-1,
|
||||
close_fds=util.closefds,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
universal_newlines=False,
|
||||
env=None)
|
||||
return p.stdout
|
||||
def gitrunlines0(self, *args, **kwargs):
|
||||
return self._gitcmd(self.runlines0, *args, **kwargs)
|
||||
|
||||
def gitrunlines(self, *args, **kwargs):
|
||||
return self._gitcmd(self.runlines, *args, **kwargs)
|
||||
|
||||
def gitpipe(self, *args, **kwargs):
|
||||
return self._gitcmd(self._run3, *args, **kwargs)
|
||||
|
||||
def gitread(self, s):
|
||||
fh = self.gitopen(s)
|
||||
@ -95,6 +62,7 @@ class convert_git(common.converter_source):
|
||||
|
||||
def __init__(self, ui, path, revs=None):
|
||||
super(convert_git, self).__init__(ui, path, revs=revs)
|
||||
common.commandline.__init__(self, ui, 'git')
|
||||
|
||||
if os.path.isdir(path + "/.git"):
|
||||
path += "/.git"
|
||||
@ -107,20 +75,20 @@ class convert_git(common.converter_source):
|
||||
if similarity < 0 or similarity > 100:
|
||||
raise error.Abort(_('similarity must be between 0 and 100'))
|
||||
if similarity > 0:
|
||||
self.simopt = '-C%d%%' % similarity
|
||||
self.simopt = ['-C%d%%' % similarity]
|
||||
findcopiesharder = ui.configbool('convert', 'git.findcopiesharder',
|
||||
False)
|
||||
if findcopiesharder:
|
||||
self.simopt += ' --find-copies-harder'
|
||||
self.simopt.append('--find-copies-harder')
|
||||
else:
|
||||
self.simopt = ''
|
||||
self.simopt = []
|
||||
|
||||
common.checktool('git', 'git')
|
||||
|
||||
self.path = path
|
||||
self.submodules = []
|
||||
|
||||
self.catfilepipe = self.gitpipe('git cat-file --batch')
|
||||
self.catfilepipe = self.gitpipe('cat-file', '--batch')
|
||||
|
||||
def after(self):
|
||||
for f in self.catfilepipe:
|
||||
@ -128,14 +96,14 @@ class convert_git(common.converter_source):
|
||||
|
||||
def getheads(self):
|
||||
if not self.revs:
|
||||
heads, ret = self.gitread('git rev-parse --branches --remotes')
|
||||
heads = heads.splitlines()
|
||||
if ret:
|
||||
output, status = self.gitrun('rev-parse', '--branches', '--remotes')
|
||||
heads = output.splitlines()
|
||||
if status:
|
||||
raise error.Abort(_('cannot retrieve git heads'))
|
||||
else:
|
||||
heads = []
|
||||
for rev in self.revs:
|
||||
rawhead, ret = self.gitread("git rev-parse --verify %s" % rev)
|
||||
rawhead, ret = self.gitrun('rev-parse', '--verify', rev)
|
||||
heads.append(rawhead[:-1])
|
||||
if ret:
|
||||
raise error.Abort(_('cannot retrieve git head "%s"') % rev)
|
||||
@ -195,7 +163,7 @@ class convert_git(common.converter_source):
|
||||
self.submodules.append(submodule(s['path'], '', s['url']))
|
||||
|
||||
def retrievegitmodules(self, version):
|
||||
modules, ret = self.gitread("git show %s:%s" % (version, '.gitmodules'))
|
||||
modules, ret = self.gitrun('show', '%s:%s' % (version, '.gitmodules'))
|
||||
if ret:
|
||||
# This can happen if a file is in the repo that has permissions
|
||||
# 160000, but there is no .gitmodules file.
|
||||
@ -211,7 +179,7 @@ class convert_git(common.converter_source):
|
||||
return
|
||||
|
||||
for m in self.submodules:
|
||||
node, ret = self.gitread("git rev-parse %s:%s" % (version, m.path))
|
||||
node, ret = self.gitrun('rev-parse', '%s:%s' % (version, m.path))
|
||||
if ret:
|
||||
continue
|
||||
m.node = node.strip()
|
||||
@ -220,15 +188,17 @@ class convert_git(common.converter_source):
|
||||
if full:
|
||||
raise error.Abort(_("convert from git does not support --full"))
|
||||
self.modecache = {}
|
||||
fh = self.gitopen("git diff-tree -z --root -m -r %s %s" % (
|
||||
self.simopt, version))
|
||||
cmd = ['diff-tree','-z', '--root', '-m', '-r'] + self.simopt + [version]
|
||||
output, status = self.gitrun(*cmd)
|
||||
if status:
|
||||
raise error.Abort(_('cannot read changes in %s') % version)
|
||||
changes = []
|
||||
copies = {}
|
||||
seen = set()
|
||||
entry = None
|
||||
subexists = [False]
|
||||
subdeleted = [False]
|
||||
difftree = fh.read().split('\x00')
|
||||
difftree = output.split('\x00')
|
||||
lcount = len(difftree)
|
||||
i = 0
|
||||
|
||||
@ -290,8 +260,6 @@ class convert_git(common.converter_source):
|
||||
if f != '.gitmodules' and fdest != '.gitmodules':
|
||||
copies[fdest] = f
|
||||
entry = None
|
||||
if fh.close():
|
||||
raise error.Abort(_('cannot read changes in %s') % version)
|
||||
|
||||
if subexists[0]:
|
||||
if subdeleted[0]:
|
||||
@ -338,17 +306,23 @@ class convert_git(common.converter_source):
|
||||
return c
|
||||
|
||||
def numcommits(self):
|
||||
return len([None for _ in self.gitopen('git rev-list --all')])
|
||||
output, ret = self.gitrunlines('rev-list', '--all')
|
||||
if ret:
|
||||
raise error.Abort(_('cannot retrieve number of commits in %s') \
|
||||
% self.path)
|
||||
return len(output)
|
||||
|
||||
def gettags(self):
|
||||
tags = {}
|
||||
alltags = {}
|
||||
fh = self.gitopen('git ls-remote --tags "%s"' % self.path,
|
||||
err=subprocess.STDOUT)
|
||||
output, status = self.gitrunlines('ls-remote', '--tags', self.path)
|
||||
|
||||
if status:
|
||||
raise error.Abort(_('cannot read tags from %s') % self.path)
|
||||
prefix = 'refs/tags/'
|
||||
|
||||
# Build complete list of tags, both annotated and bare ones
|
||||
for line in fh:
|
||||
for line in output:
|
||||
line = line.strip()
|
||||
if line.startswith("error:") or line.startswith("fatal:"):
|
||||
raise error.Abort(_('cannot read tags from %s') % self.path)
|
||||
@ -356,8 +330,6 @@ class convert_git(common.converter_source):
|
||||
if not tag.startswith(prefix):
|
||||
continue
|
||||
alltags[tag[len(prefix):]] = node
|
||||
if fh.close():
|
||||
raise error.Abort(_('cannot read tags from %s') % self.path)
|
||||
|
||||
# Filter out tag objects for annotated tag refs
|
||||
for tag in alltags:
|
||||
@ -374,18 +346,20 @@ class convert_git(common.converter_source):
|
||||
def getchangedfiles(self, version, i):
|
||||
changes = []
|
||||
if i is None:
|
||||
fh = self.gitopen("git diff-tree --root -m -r %s" % version)
|
||||
for l in fh:
|
||||
output, status = self.gitrunlines('diff-tree', '--root', '-m',
|
||||
'-r', version)
|
||||
if status:
|
||||
raise error.Abort(_('cannot read changes in %s') % version)
|
||||
for l in output:
|
||||
if "\t" not in l:
|
||||
continue
|
||||
m, f = l[:-1].split("\t")
|
||||
changes.append(f)
|
||||
else:
|
||||
fh = self.gitopen('git diff-tree --name-only --root -r %s '
|
||||
'"%s^%s" --' % (version, version, i + 1))
|
||||
changes = [f.rstrip('\n') for f in fh]
|
||||
if fh.close():
|
||||
raise error.Abort(_('cannot read changes in %s') % version)
|
||||
output, status = self.gitrunlines('diff-tree', '--name-only',
|
||||
'--root', '-r', version,
|
||||
'%s^%s' % (version, i + 1), '--')
|
||||
changes = [f.rstrip('\n') for f in output]
|
||||
|
||||
return changes
|
||||
|
||||
@ -405,8 +379,8 @@ class convert_git(common.converter_source):
|
||||
])
|
||||
|
||||
try:
|
||||
fh = self.gitopen('git show-ref', err=subprocess.PIPE)
|
||||
for line in fh:
|
||||
output, status = self.gitrunlines('show-ref')
|
||||
for line in output:
|
||||
line = line.strip()
|
||||
rev, name = line.split(None, 1)
|
||||
# Process each type of branch
|
||||
|
@ -205,7 +205,7 @@ static struct flist *decode(const char *bin, Py_ssize_t len)
|
||||
int pos = 0;
|
||||
|
||||
/* assume worst case size, we won't have many of these lists */
|
||||
l = lalloc(len / 12);
|
||||
l = lalloc(len / 12 + 1);
|
||||
if (!l)
|
||||
return NULL;
|
||||
|
||||
@ -215,10 +215,10 @@ static struct flist *decode(const char *bin, Py_ssize_t len)
|
||||
lt->start = getbe32(bin + pos);
|
||||
lt->end = getbe32(bin + pos + 4);
|
||||
lt->len = getbe32(bin + pos + 8);
|
||||
if (lt->start > lt->end)
|
||||
break; /* sanity check */
|
||||
lt->data = bin + pos + 12;
|
||||
pos += 12 + lt->len;
|
||||
if (lt->start > lt->end || lt->len < 0)
|
||||
break; /* sanity check */
|
||||
lt++;
|
||||
}
|
||||
|
||||
|
@ -1385,6 +1385,11 @@ class gitsubrepo(abstractsubrepo):
|
||||
are not supported and very probably fail.
|
||||
"""
|
||||
self.ui.debug('%s: git %s\n' % (self._relpath, ' '.join(commands)))
|
||||
if env is None:
|
||||
env = os.environ.copy()
|
||||
# fix for Git CVE-2015-7545
|
||||
if 'GIT_ALLOW_PROTOCOL' not in env:
|
||||
env['GIT_ALLOW_PROTOCOL'] = 'file:git:http:https:ssh'
|
||||
# unless ui.quiet is set, print git's stderr,
|
||||
# which is mostly progress and useful info
|
||||
errpipe = None
|
||||
|
@ -714,7 +714,7 @@ damage git repository by renaming a commit object
|
||||
$ COMMIT_OBJ=1c/0ce3c5886f83a1d78a7b517cdff5cf9ca17bdd
|
||||
$ mv git-repo4/.git/objects/$COMMIT_OBJ git-repo4/.git/objects/$COMMIT_OBJ.tmp
|
||||
$ hg convert git-repo4 git-repo4-broken-hg 2>&1 | grep 'abort:'
|
||||
abort: cannot read tags from git-repo4/.git
|
||||
abort: cannot retrieve number of commits in git-repo4/.git
|
||||
$ mv git-repo4/.git/objects/$COMMIT_OBJ.tmp git-repo4/.git/objects/$COMMIT_OBJ
|
||||
damage git repository by renaming a blob object
|
||||
|
||||
@ -729,3 +729,20 @@ damage git repository by renaming a tree object
|
||||
$ mv git-repo4/.git/objects/$TREE_OBJ git-repo4/.git/objects/$TREE_OBJ.tmp
|
||||
$ hg convert git-repo4 git-repo4-broken-hg 2>&1 | grep 'abort:'
|
||||
abort: cannot read changes in 1c0ce3c5886f83a1d78a7b517cdff5cf9ca17bdd
|
||||
|
||||
test for escaping the repo name (CVE-2016-3069)
|
||||
|
||||
$ git init '`echo pwned >COMMAND-INJECTION`'
|
||||
Initialized empty Git repository in $TESTTMP/`echo pwned >COMMAND-INJECTION`/.git/
|
||||
$ cd '`echo pwned >COMMAND-INJECTION`'
|
||||
$ git commit -q --allow-empty -m 'empty'
|
||||
$ cd ..
|
||||
$ hg convert '`echo pwned >COMMAND-INJECTION`' 'converted'
|
||||
initializing destination converted repository
|
||||
scanning source...
|
||||
sorting...
|
||||
converting...
|
||||
0 empty
|
||||
updating bookmarks
|
||||
$ test -f COMMAND-INJECTION
|
||||
[1]
|
||||
|
15
tests/test-revlog.t
Normal file
15
tests/test-revlog.t
Normal file
@ -0,0 +1,15 @@
|
||||
Test for CVE-2016-3630
|
||||
|
||||
$ hg init
|
||||
|
||||
>>> open("a.i", "w").write(
|
||||
... """eJxjYGZgZIAAYQYGxhgom+k/FMx8YKx9ZUaKSOyqo4cnuKb8mbqHV5cBCVTMWb1Cwqkhe4Gsg9AD
|
||||
... Joa3dYtcYYYBAQ8Qr4OqZAYRICPTSr5WKd/42rV36d+8/VmrNpv7NP1jQAXrQE4BqQUARngwVA=="""
|
||||
... .decode("base64").decode("zlib"))
|
||||
|
||||
$ hg debugindex a.i
|
||||
rev offset length delta linkrev nodeid p1 p2
|
||||
0 0 19 -1 2 99e0332bd498 000000000000 000000000000
|
||||
1 19 12 0 3 6674f57a23d8 99e0332bd498 000000000000
|
||||
$ hg debugdata a.i 1 2>&1 | grep decoded
|
||||
mpatch.mpatchError: patch cannot be decoded
|
@ -1132,4 +1132,36 @@ make sure we show changed files, rather than changed subtrees
|
||||
? s/foobar.orig
|
||||
? s/snake.python.orig
|
||||
|
||||
test for Git CVE-2016-3068
|
||||
$ hg init malicious-subrepository
|
||||
$ cd malicious-subrepository
|
||||
$ echo "s = [git]ext::sh -c echo% pwned% >&2" > .hgsub
|
||||
$ git init s
|
||||
Initialized empty Git repository in $TESTTMP/tc/malicious-subrepository/s/.git/
|
||||
$ cd s
|
||||
$ git commit --allow-empty -m 'empty'
|
||||
[master (root-commit) 153f934] empty
|
||||
$ cd ..
|
||||
$ hg add .hgsub
|
||||
$ hg commit -m "add subrepo"
|
||||
$ cd ..
|
||||
$ env -u GIT_ALLOW_PROTOCOL hg clone malicious-subrepository malicious-subrepository-protected
|
||||
Cloning into '$TESTTMP/tc/malicious-subrepository-protected/s'...
|
||||
fatal: transport 'ext' not allowed
|
||||
updating to branch default
|
||||
cloning subrepo s from ext::sh -c echo% pwned% >&2
|
||||
abort: git clone error 128 in s (in subrepo s)
|
||||
[255]
|
||||
|
||||
whitelisting of ext should be respected (that's the git submodule behaviour)
|
||||
$ env GIT_ALLOW_PROTOCOL=ext hg clone malicious-subrepository malicious-subrepository-clone-allowed
|
||||
Cloning into '$TESTTMP/tc/malicious-subrepository-clone-allowed/s'...
|
||||
pwned
|
||||
fatal: Could not read from remote repository.
|
||||
|
||||
Please make sure you have the correct access rights
|
||||
and the repository exists.
|
||||
updating to branch default
|
||||
cloning subrepo s from ext::sh -c echo% pwned% >&2
|
||||
abort: git clone error 128 in s (in subrepo s)
|
||||
[255]
|
||||
|
Loading…
Reference in New Issue
Block a user