~ubuntu-branches/ubuntu/trusty/mercurial/trusty-security

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
Backport of:

Origin: c02a05cc6f5e661b09b0b0c65ec7bc874e161f9c (backport)
# HG changeset patch
# User Augie Fackler <raf@durin42.com>
# Date 1418753297 18000
# Node ID c02a05cc6f5e661b09b0b0c65ec7bc874e161f9c
# Parent  7a5bcd471f2ef302613b8551a79081d46d04be6e
pathauditor: check for codepoints ignored on OS X

Index: mercurial-2.8.2/mercurial/scmutil.py
===================================================================
--- mercurial-2.8.2.orig/mercurial/scmutil.py
+++ mercurial-2.8.2/mercurial/scmutil.py
@@ -5,6 +5,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
+import encoding
 from i18n import _
 from mercurial.node import nullrev
 import util, error, osutil, revset, similar, encoding, phases, parsers
@@ -19,6 +20,9 @@ else:
 systemrcpath = scmplatform.systemrcpath
 userrcpath = scmplatform.userrcpath
 
+def _lowerclean(s):
+    return encoding.hfsignoreclean(s.lower())
+
 def nochangesfound(ui, repo, excluded=None):
     '''Report no changes for push/pull, excluded is None or a list of
     nodes excluded from the push/pull.
@@ -143,11 +147,11 @@ class pathauditor(object):
             raise util.Abort(_("path ends in directory separator: %s") % path)
         parts = util.splitpath(path)
         if (os.path.splitdrive(path)[0]
-            or parts[0].lower() in ('.hg', '.hg.', '')
+            or _lowerclean(parts[0]) in ('.hg', '.hg.', '')
             or os.pardir in parts):
             raise util.Abort(_("path contains illegal component: %s") % path)
-        if '.hg' in path.lower():
-            lparts = [p.lower() for p in parts]
+        if '.hg' in _lowerclean(path):
+            lparts = [_lowerclean(p.lower()) for p in parts]
             for p in '.hg', '.hg.':
                 if p in lparts[1:]:
                     pos = lparts.index(p)
Index: mercurial-2.8.2/tests/test-commit.t
===================================================================
--- mercurial-2.8.2.orig/tests/test-commit.t
+++ mercurial-2.8.2/tests/test-commit.t
@@ -306,4 +306,21 @@ commit copy
        0         0       6  .....       0 26d3ca0dfd18 000000000000 000000000000 (re)
        1         6       7  .....       1 d267bddd54f7 26d3ca0dfd18 000000000000 (re)
 
+verify pathauditor blocks evil filepaths
+  $ cat > evil-commit.py <<EOF
+  > from mercurial import ui, hg, context, node
+  > notrc = u".h\u200cg".encode('utf-8') + '/hgrc'
+  > u = ui.ui()
+  > r = hg.repository(u, '.')
+  > def filectxfn(repo, memctx, path):
+  >     return context.memfilectx(path, '[hooks]\nupdate = echo owned')
+  > c = context.memctx(r, [r['tip'].node(), node.nullid],
+  >                    'evil', [notrc], filectxfn, 0)
+  > r.commitctx(c)
+  > EOF
+  $ $PYTHON evil-commit.py
+  $ hg co --clean tip
+  abort: path contains illegal component: .h\xe2\x80\x8cg/hgrc (esc)
+  [255]
+
   $ cd ..