qulogic / rpms / mercurial

Forked from rpms/mercurial 3 years ago
Clone
1f5a365
# HG changeset patch
1f5a365
# User Mateusz Kwapich <mitrandir@fb.com>
1f5a365
# Date 1458691511 25200
1f5a365
#      Tue Mar 22 17:05:11 2016 -0700
1f5a365
# Branch stable
1f5a365
# Node ID cdda7b96afff3433eafdeeb83ded83a5b25b7a5b
1f5a365
# Parent  a47006d8d01537c6a765ac77b66bf1c73b4cf7db
1f5a365
convert: rewrite calls to Git to use the new shelling mechanism (SEC)
1f5a365
1f5a365
CVE-2016-3069 (2/5)
1f5a365
1f5a365
One test output changed because we were ignoring git return code in numcommits
1f5a365
before.
1f5a365
1f5a365
diff --git a/hgext/convert/git.py b/hgext/convert/git.py
1f5a365
--- a/hgext/convert/git.py
1f5a365
+++ b/hgext/convert/git.py
1f5a365
@@ -115,13 +115,13 @@ class convert_git(converter_source, comm
1f5a365
         if similarity < 0 or similarity > 100:
1f5a365
             raise util.Abort(_('similarity must be between 0 and 100'))
1f5a365
         if similarity > 0:
1f5a365
-            self.simopt = '-C%d%%' % similarity
1f5a365
+            self.simopt = ['-C%d%%' % similarity]
1f5a365
             findcopiesharder = ui.configbool('convert', 'git.findcopiesharder',
1f5a365
                                              False)
1f5a365
             if findcopiesharder:
1f5a365
-                self.simopt += ' --find-copies-harder'
1f5a365
+                self.simopt.append('--find-copies-harder')
1f5a365
         else:
1f5a365
-            self.simopt = ''
1f5a365
+            self.simopt = []
1f5a365
 
1f5a365
         checktool('git', 'git')
1f5a365
 
1f5a365
@@ -136,14 +136,14 @@ class convert_git(converter_source, comm
1f5a365
 
1f5a365
     def getheads(self):
1f5a365
         if not self.revs:
1f5a365
-            heads, ret = self.gitread('git rev-parse --branches --remotes')
1f5a365
-            heads = heads.splitlines()
1f5a365
-            if ret:
1f5a365
+            output, status = self.gitrun('rev-parse', '--branches', '--remotes')
1f5a365
+            heads = output.splitlines()
1f5a365
+            if status:
1f5a365
                 raise util.Abort(_('cannot retrieve git heads'))
1f5a365
         else:
1f5a365
             heads = []
1f5a365
             for rev in self.revs:
1f5a365
-                rawhead, ret = self.gitread("git rev-parse --verify %s" % rev)
1f5a365
+                rawhead, ret = self.gitrun('rev-parse', '--verify', rev)
1f5a365
                 heads.append(rawhead[:-1])
1f5a365
                 if ret:
1f5a365
                     raise util.Abort(_('cannot retrieve git head "%s"') % rev)
1f5a365
@@ -203,7 +203,7 @@ class convert_git(converter_source, comm
1f5a365
                 self.submodules.append(submodule(s['path'], '', s['url']))
1f5a365
 
1f5a365
     def retrievegitmodules(self, version):
1f5a365
-        modules, ret = self.gitread("git show %s:%s" % (version, '.gitmodules'))
1f5a365
+        modules, ret = self.gitrun('show', '%s:%s' % (version, '.gitmodules'))
1f5a365
         if ret:
1f5a365
             # This can happen if a file is in the repo that has permissions
1f5a365
             # 160000, but there is no .gitmodules file.
1f5a365
@@ -219,7 +219,7 @@ class convert_git(converter_source, comm
1f5a365
             return
1f5a365
 
1f5a365
         for m in self.submodules:
1f5a365
-            node, ret = self.gitread("git rev-parse %s:%s" % (version, m.path))
1f5a365
+            node, ret = self.gitrun('rev-parse', '%s:%s' % (version, m.path))
1f5a365
             if ret:
1f5a365
                 continue
1f5a365
             m.node = node.strip()
1f5a365
@@ -228,15 +228,17 @@ class convert_git(converter_source, comm
1f5a365
         if full:
1f5a365
             raise util.Abort(_("convert from git do not support --full"))
1f5a365
         self.modecache = {}
1f5a365
-        fh = self.gitopen("git diff-tree -z --root -m -r %s %s" % (
1f5a365
-            self.simopt, version))
1f5a365
+        cmd = ['diff-tree','-z', '--root', '-m', '-r'] + self.simopt + [version]
1f5a365
+        output, status = self.gitrun(*cmd)
1f5a365
+        if status:
1f5a365
+            raise util.Abort(_('cannot read changes in %s') % version)
1f5a365
         changes = []
1f5a365
         copies = {}
1f5a365
         seen = set()
1f5a365
         entry = None
1f5a365
         subexists = [False]
1f5a365
         subdeleted = [False]
1f5a365
-        difftree = fh.read().split('\x00')
1f5a365
+        difftree = output.split('\x00')
1f5a365
         lcount = len(difftree)
1f5a365
         i = 0
1f5a365
 
1f5a365
@@ -292,8 +294,6 @@ class convert_git(converter_source, comm
1f5a365
                     if f != '.gitmodules' and fdest != '.gitmodules':
1f5a365
                         copies[fdest] = f
1f5a365
             entry = None
1f5a365
-        if fh.close():
1f5a365
-            raise util.Abort(_('cannot read changes in %s') % version)
1f5a365
 
1f5a365
         if subexists[0]:
1f5a365
             if subdeleted[0]:
1f5a365
@@ -339,17 +339,23 @@ class convert_git(converter_source, comm
1f5a365
         return c
1f5a365
 
1f5a365
     def numcommits(self):
1f5a365
-        return len([None for _ in self.gitopen('git rev-list --all')])
1f5a365
+        output, ret = self.gitrunlines('rev-list', '--all')
1f5a365
+        if ret:
1f5a365
+            raise util.Abort(_('cannot retrieve number of commits in %s') \
1f5a365
+                              % self.path)
1f5a365
+        return len(output)
1f5a365
 
1f5a365
     def gettags(self):
1f5a365
         tags = {}
1f5a365
         alltags = {}
1f5a365
-        fh = self.gitopen('git ls-remote --tags "%s"' % self.path,
1f5a365
-                          err=subprocess.STDOUT)
1f5a365
+        output, status = self.gitrunlines('ls-remote', '--tags', self.path)
1f5a365
+
1f5a365
+        if status:
1f5a365
+            raise util.Abort(_('cannot read tags from %s') % self.path)
1f5a365
         prefix = 'refs/tags/'
1f5a365
 
1f5a365
         # Build complete list of tags, both annotated and bare ones
1f5a365
-        for line in fh:
1f5a365
+        for line in output:
1f5a365
             line = line.strip()
1f5a365
             if line.startswith("error:") or line.startswith("fatal:"):
1f5a365
                 raise util.Abort(_('cannot read tags from %s') % self.path)
1f5a365
@@ -357,8 +363,6 @@ class convert_git(converter_source, comm
1f5a365
             if not tag.startswith(prefix):
1f5a365
                 continue
1f5a365
             alltags[tag[len(prefix):]] = node
1f5a365
-        if fh.close():
1f5a365
-            raise util.Abort(_('cannot read tags from %s') % self.path)
1f5a365
 
1f5a365
         # Filter out tag objects for annotated tag refs
1f5a365
         for tag in alltags:
1f5a365
@@ -375,18 +379,20 @@ class convert_git(converter_source, comm
1f5a365
     def getchangedfiles(self, version, i):
1f5a365
         changes = []
1f5a365
         if i is None:
1f5a365
-            fh = self.gitopen("git diff-tree --root -m -r %s" % version)
1f5a365
-            for l in fh:
1f5a365
+            output, status = self.gitrunlines('diff-tree', '--root', '-m',
1f5a365
+                                              '-r', version)
1f5a365
+            if status:
1f5a365
+                raise util.Abort(_('cannot read changes in %s') % version)
1f5a365
+            for l in output:
1f5a365
                 if "\t" not in l:
1f5a365
                     continue
1f5a365
                 m, f = l[:-1].split("\t")
1f5a365
                 changes.append(f)
1f5a365
         else:
1f5a365
-            fh = self.gitopen('git diff-tree --name-only --root -r %s '
1f5a365
-                              '"%s^%s" --' % (version, version, i + 1))
1f5a365
-            changes = [f.rstrip('\n') for f in fh]
1f5a365
-        if fh.close():
1f5a365
-            raise util.Abort(_('cannot read changes in %s') % version)
1f5a365
+            output, status = self.gitrunlines('diff-tree', '--name-only',
1f5a365
+                                              '--root', '-r', version,
1f5a365
+                                              '%s^%s' % (version, i + 1), '--')
1f5a365
+            changes = [f.rstrip('\n') for f in output]
1f5a365
 
1f5a365
         return changes
1f5a365
 
1f5a365
@@ -399,14 +405,14 @@ class convert_git(converter_source, comm
1f5a365
 
1f5a365
         # factor two commands
1f5a365
         remoteprefix = self.ui.config('convert', 'git.remoteprefix', 'remote')
1f5a365
-        gitcmd = { remoteprefix + '/': 'git ls-remote --heads origin',
1f5a365
-                                   '': 'git show-ref'}
1f5a365
+        gitcmd = { remoteprefix + '/': ['ls-remote', '--heads', 'origin'],
1f5a365
+                                   '': ['show-ref']}
1f5a365
 
1f5a365
         # Origin heads
1f5a365
         for reftype in gitcmd:
1f5a365
             try:
1f5a365
-                fh = self.gitopen(gitcmd[reftype], err=subprocess.PIPE)
1f5a365
-                for line in fh:
1f5a365
+                output, status = self.gitrunlines(*gitcmd[reftype])
1f5a365
+                for line in output:
1f5a365
                     line = line.strip()
1f5a365
                     rev, name = line.split(None, 1)
1f5a365
                     if not name.startswith(prefix):
1f5a365
diff --git a/tests/test-convert-git.t b/tests/test-convert-git.t
1f5a365
--- a/tests/test-convert-git.t
1f5a365
+++ b/tests/test-convert-git.t
1f5a365
@@ -534,7 +534,6 @@ test missing .gitmodules
1f5a365
   $ git commit -q -m "missing .gitmodules"
1f5a365
   $ cd ..
1f5a365
   $ hg convert git-repo6 hg-repo6 --traceback
1f5a365
-  fatal: Path '.gitmodules' does not exist in '*' (glob)
1f5a365
   initializing destination hg-repo6 repository
1f5a365
   scanning source...
1f5a365
   sorting...
1f5a365
@@ -689,7 +688,7 @@ damage git repository by renaming a comm
1f5a365
   $ COMMIT_OBJ=1c/0ce3c5886f83a1d78a7b517cdff5cf9ca17bdd
1f5a365
   $ mv git-repo4/.git/objects/$COMMIT_OBJ git-repo4/.git/objects/$COMMIT_OBJ.tmp
1f5a365
   $ hg convert git-repo4 git-repo4-broken-hg 2>&1 | grep 'abort:'
1f5a365
-  abort: cannot read tags from git-repo4/.git
1f5a365
+  abort: cannot retrieve number of commits in git-repo4/.git
1f5a365
   $ mv git-repo4/.git/objects/$COMMIT_OBJ.tmp git-repo4/.git/objects/$COMMIT_OBJ
1f5a365
 damage git repository by renaming a blob object
1f5a365