--- a/.hgsigs Sat Oct 21 17:46:41 2017 +0900
+++ b/.hgsigs Tue Nov 07 13:18:49 2017 -0500
@@ -154,3 +154,4 @@
2f427b57bf9019c6dc3750baa539dc22c1be50f6 0 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
--- a/.hgtags Sat Oct 21 17:46:41 2017 +0900
+++ b/.hgtags Tue Nov 07 13:18:49 2017 -0500
@@ -167,3 +167,4 @@
2f427b57bf9019c6dc3750baa539dc22c1be50f6 4.3.3
1e2454b60e5936f5e77498cab2648db469504487 4.4-rc
0ccb43d4cf01d013ae05917ec4f305509f851b2d 4.4
+cabc840ffdee8a72f3689fb77dd74d04fdc2bc04 4.4.1
--- a/hgext/share.py Sat Oct 21 17:46:41 2017 +0900
+++ b/hgext/share.py Tue Nov 07 13:18:49 2017 -0500
@@ -63,16 +63,6 @@
# leave the attribute unspecified.
testedwith = 'ships-with-hg-core'
-configtable = {}
-configitem = registrar.configitem(configtable)
-
-configitem('share', 'pool',
- default=None,
-)
-configitem('share', 'poolnaming',
- default='identity',
-)
-
@command('share',
[('U', 'noupdate', None, _('do not create a working directory')),
('B', 'bookmarks', None, _('also share bookmarks')),
--- a/mercurial/cmdutil.py Sat Oct 21 17:46:41 2017 +0900
+++ b/mercurial/cmdutil.py Tue Nov 07 13:18:49 2017 -0500
@@ -570,9 +570,8 @@
unresolvedlist = [f for f in mergestate.unresolved() if m(f)]
if unresolvedlist:
mergeliststr = '\n'.join(
- [' %s' % os.path.relpath(
- os.path.join(repo.root, path),
- pycompat.getcwd()) for path in unresolvedlist])
+ [' %s' % util.pathto(repo.root, pycompat.getcwd(), path)
+ for path in unresolvedlist])
msg = _('''Unresolved merge conflicts:
%s
--- a/mercurial/configitems.py Sat Oct 21 17:46:41 2017 +0900
+++ b/mercurial/configitems.py Tue Nov 07 13:18:49 2017 -0500
@@ -787,6 +787,12 @@
coreconfigitem('server', 'zliblevel',
default=-1,
)
+coreconfigitem('share', 'pool',
+ default=None,
+)
+coreconfigitem('share', 'poolnaming',
+ default='identity',
+)
coreconfigitem('smtp', 'host',
default=None,
)
@@ -808,6 +814,18 @@
coreconfigitem('sparse', 'missingwarning',
default=True,
)
+coreconfigitem('subrepos', 'allowed',
+ default=dynamicdefault, # to make backporting simpler
+)
+coreconfigitem('subrepos', 'hg:allowed',
+ default=dynamicdefault,
+)
+coreconfigitem('subrepos', 'git:allowed',
+ default=dynamicdefault,
+)
+coreconfigitem('subrepos', 'svn:allowed',
+ default=dynamicdefault,
+)
coreconfigitem('templates', '.*',
default=None,
generic=True,
--- a/mercurial/help/config.txt Sat Oct 21 17:46:41 2017 +0900
+++ b/mercurial/help/config.txt Tue Nov 07 13:18:49 2017 -0500
@@ -1893,6 +1893,47 @@
doesn't match the full path, an attempt is made to apply it on the
relative path alone. The rules are applied in definition order.
+``subrepos``
+------------
+
+This section contains options that control the behavior of the
+subrepositories feature. See also :hg:`help subrepos`.
+
+Security note: auditing in Mercurial is known to be insufficient to
+prevent clone-time code execution with carefully constructed Git
+subrepos. It is unknown if a similar detect is present in Subversion
+subrepos. Both Git and Subversion subrepos are disabled by default
+out of security concerns. These subrepo types can be enabled using
+the respective options below.
+
+``allowed``
+ Whether subrepositories are allowed in the working directory.
+
+ When false, commands involving subrepositories (like :hg:`update`)
+ will fail for all subrepository types.
+ (default: true)
+
+``hg:allowed``
+ Whether Mercurial subrepositories are allowed in the working
+ directory. This option only has an effect if ``subrepos.allowed``
+ is true.
+ (default: true)
+
+``git:allowed``
+ Whether Git subrepositories are allowed in the working directory.
+ This option only has an effect if ``subrepos.allowed`` is true.
+
+ See the security note above before enabling Git subrepos.
+ (default: false)
+
+``svn:allowed``
+ Whether Subversion subrepositories are allowed in the working
+ directory. This option only has an effect if ``subrepos.allowed``
+ is true.
+
+ See the security note above before enabling Subversion subrepos.
+ (default: false)
+
``templatealias``
-----------------
--- a/mercurial/hg.py Sat Oct 21 17:46:41 2017 +0900
+++ b/mercurial/hg.py Tue Nov 07 13:18:49 2017 -0500
@@ -243,7 +243,9 @@
try:
sharedpath = os.path.relpath(sharedpath, destvfs.base)
requirements += 'relshared\n'
- except IOError as e:
+ except (IOError, ValueError) as e:
+ # ValueError is raised on Windows if the drive letters differ on
+ # each path
raise error.Abort(_('cannot calculate relative path'),
hint=str(e))
else:
--- a/mercurial/pathutil.py Sat Oct 21 17:46:41 2017 +0900
+++ b/mercurial/pathutil.py Tue Nov 07 13:18:49 2017 -0500
@@ -135,7 +135,47 @@
return False
def canonpath(root, cwd, myname, auditor=None):
- '''return the canonical path of myname, given cwd and root'''
+ '''return the canonical path of myname, given cwd and root
+
+ >>> def check(root, cwd, myname):
+ ... a = pathauditor(root, realfs=False)
+ ... try:
+ ... return canonpath(root, cwd, myname, a)
+ ... except error.Abort:
+ ... return 'aborted'
+ >>> def unixonly(root, cwd, myname, expected='aborted'):
+ ... if pycompat.iswindows:
+ ... return expected
+ ... return check(root, cwd, myname)
+ >>> def winonly(root, cwd, myname, expected='aborted'):
+ ... if not pycompat.iswindows:
+ ... return expected
+ ... return check(root, cwd, myname)
+ >>> winonly(b'd:\\\\repo', b'c:\\\\dir', b'filename')
+ 'aborted'
+ >>> winonly(b'c:\\\\repo', b'c:\\\\dir', b'filename')
+ 'aborted'
+ >>> winonly(b'c:\\\\repo', b'c:\\\\', b'filename')
+ 'aborted'
+ >>> winonly(b'c:\\\\repo', b'c:\\\\', b'repo\\\\filename',
+ ... b'filename')
+ 'filename'
+ >>> winonly(b'c:\\\\repo', b'c:\\\\repo', b'filename', b'filename')
+ 'filename'
+ >>> winonly(b'c:\\\\repo', b'c:\\\\repo\\\\subdir', b'filename',
+ ... b'subdir/filename')
+ 'subdir/filename'
+ >>> unixonly(b'/repo', b'/dir', b'filename')
+ 'aborted'
+ >>> unixonly(b'/repo', b'/', b'filename')
+ 'aborted'
+ >>> unixonly(b'/repo', b'/', b'repo/filename', b'filename')
+ 'filename'
+ >>> unixonly(b'/repo', b'/repo', b'filename', b'filename')
+ 'filename'
+ >>> unixonly(b'/repo', b'/repo/subdir', b'filename', b'subdir/filename')
+ 'subdir/filename'
+ '''
if util.endswithsep(root):
rootsep = root
else:
--- a/mercurial/subrepo.py Sat Oct 21 17:46:41 2017 +0900
+++ b/mercurial/subrepo.py Tue Nov 07 13:18:49 2017 -0500
@@ -359,6 +359,33 @@
"in '%s'\n") % vfs.join(dirname))
vfs.unlink(vfs.reljoin(dirname, f))
+def _auditsubrepopath(repo, path):
+ # auditor doesn't check if the path itself is a symlink
+ pathutil.pathauditor(repo.root)(path)
+ if repo.wvfs.islink(path):
+ raise error.Abort(_("subrepo '%s' traverses symbolic link") % path)
+
+SUBREPO_ALLOWED_DEFAULTS = {
+ 'hg': True,
+ 'git': False,
+ 'svn': False,
+}
+
+def _checktype(ui, kind):
+ # subrepos.allowed is a master kill switch. If disabled, subrepos are
+ # disabled period.
+ if not ui.configbool('subrepos', 'allowed', True):
+ raise error.Abort(_('subrepos not enabled'),
+ hint=_("see 'hg help config.subrepos' for details"))
+
+ default = SUBREPO_ALLOWED_DEFAULTS.get(kind, False)
+ if not ui.configbool('subrepos', '%s:allowed' % kind, default):
+ raise error.Abort(_('%s subrepos not allowed') % kind,
+ hint=_("see 'hg help config.subrepos' for details"))
+
+ if kind not in types:
+ raise error.Abort(_('unknown subrepo type %s') % kind)
+
def subrepo(ctx, path, allowwdir=False, allowcreate=True):
"""return instance of the right subrepo class for subrepo in path"""
# subrepo inherently violates our import layering rules
@@ -369,10 +396,10 @@
from . import hg as h
hg = h
- pathutil.pathauditor(ctx.repo().root)(path)
+ repo = ctx.repo()
+ _auditsubrepopath(repo, path)
state = ctx.substate[path]
- if state[2] not in types:
- raise error.Abort(_('unknown subrepo type %s') % state[2])
+ _checktype(repo.ui, state[2])
if allowwdir:
state = (state[0], ctx.subrev(path), state[2])
return types[state[2]](ctx, path, state[:2], allowcreate)
@@ -387,10 +414,10 @@
from . import hg as h
hg = h
- pathutil.pathauditor(ctx.repo().root)(path)
+ repo = ctx.repo()
+ _auditsubrepopath(repo, path)
state = ctx.substate[path]
- if state[2] not in types:
- raise error.Abort(_('unknown subrepo type %s') % state[2])
+ _checktype(repo.ui, state[2])
subrev = ''
if state[2] == 'hg':
subrev = "0" * 40
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-audit-subrepo.t Tue Nov 07 13:18:49 2017 -0500
@@ -0,0 +1,132 @@
+Test illegal name
+-----------------
+
+on commit:
+
+ $ hg init hgname
+ $ cd hgname
+ $ mkdir sub
+ $ hg init sub/.hg
+ $ echo 'sub/.hg = sub/.hg' >> .hgsub
+ $ hg ci -qAm 'add subrepo "sub/.hg"'
+ abort: path 'sub/.hg' is inside nested repo 'sub'
+ [255]
+
+prepare tampered repo (including the commit above):
+
+ $ hg import --bypass -qm 'add subrepo "sub/.hg"' - <<'EOF'
+ > diff --git a/.hgsub b/.hgsub
+ > new file mode 100644
+ > --- /dev/null
+ > +++ b/.hgsub
+ > @@ -0,0 +1,1 @@
+ > +sub/.hg = sub/.hg
+ > diff --git a/.hgsubstate b/.hgsubstate
+ > new file mode 100644
+ > --- /dev/null
+ > +++ b/.hgsubstate
+ > @@ -0,0 +1,1 @@
+ > +0000000000000000000000000000000000000000 sub/.hg
+ > EOF
+ $ cd ..
+
+on clone (and update):
+
+ $ hg clone -q hgname hgname2
+ abort: path 'sub/.hg' is inside nested repo 'sub'
+ [255]
+
+Test direct symlink traversal
+-----------------------------
+
+#if symlink
+
+on commit:
+
+ $ mkdir hgsymdir
+ $ hg init hgsymdir/root
+ $ cd hgsymdir/root
+ $ ln -s ../out
+ $ hg ci -qAm 'add symlink "out"'
+ $ hg init ../out
+ $ echo 'out = out' >> .hgsub
+ $ hg ci -qAm 'add subrepo "out"'
+ abort: subrepo 'out' traverses symbolic link
+ [255]
+
+prepare tampered repo (including the commit above):
+
+ $ hg import --bypass -qm 'add subrepo "out"' - <<'EOF'
+ > diff --git a/.hgsub b/.hgsub
+ > new file mode 100644
+ > --- /dev/null
+ > +++ b/.hgsub
+ > @@ -0,0 +1,1 @@
+ > +out = out
+ > diff --git a/.hgsubstate b/.hgsubstate
+ > new file mode 100644
+ > --- /dev/null
+ > +++ b/.hgsubstate
+ > @@ -0,0 +1,1 @@
+ > +0000000000000000000000000000000000000000 out
+ > EOF
+ $ cd ../..
+
+on clone (and update):
+
+ $ mkdir hgsymdir2
+ $ hg clone -q hgsymdir/root hgsymdir2/root
+ abort: subrepo 'out' traverses symbolic link
+ [255]
+ $ ls hgsymdir2
+ root
+
+#endif
+
+Test indirect symlink traversal
+-------------------------------
+
+#if symlink
+
+on commit:
+
+ $ mkdir hgsymin
+ $ hg init hgsymin/root
+ $ cd hgsymin/root
+ $ ln -s ../out
+ $ hg ci -qAm 'add symlink "out"'
+ $ mkdir ../out
+ $ hg init ../out/sub
+ $ echo 'out/sub = out/sub' >> .hgsub
+ $ hg ci -qAm 'add subrepo "out/sub"'
+ abort: path 'out/sub' traverses symbolic link 'out'
+ [255]
+
+prepare tampered repo (including the commit above):
+
+ $ hg import --bypass -qm 'add subrepo "out/sub"' - <<'EOF'
+ > diff --git a/.hgsub b/.hgsub
+ > new file mode 100644
+ > --- /dev/null
+ > +++ b/.hgsub
+ > @@ -0,0 +1,1 @@
+ > +out/sub = out/sub
+ > diff --git a/.hgsubstate b/.hgsubstate
+ > new file mode 100644
+ > --- /dev/null
+ > +++ b/.hgsubstate
+ > @@ -0,0 +1,1 @@
+ > +0000000000000000000000000000000000000000 out/sub
+ > EOF
+ $ cd ../..
+
+on clone (and update):
+
+ $ mkdir hgsymin2
+ $ hg clone -q hgsymin/root hgsymin2/root
+ abort: path 'out/sub' traverses symbolic link 'out'
+ [255]
+ $ ls hgsymin2
+ root
+
+#endif
--- a/tests/test-convert-git.t Sat Oct 21 17:46:41 2017 +0900
+++ b/tests/test-convert-git.t Tue Nov 07 13:18:49 2017 -0500
@@ -6,6 +6,10 @@
$ echo "autocrlf = false" >> $HOME/.gitconfig
$ echo "[extensions]" >> $HGRCPATH
$ echo "convert=" >> $HGRCPATH
+ $ cat >> $HGRCPATH <<EOF
+ > [subrepos]
+ > git:allowed = true
+ > EOF
$ GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
$ GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
$ GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
--- a/tests/test-mq-subrepo-svn.t Sat Oct 21 17:46:41 2017 +0900
+++ b/tests/test-mq-subrepo-svn.t Tue Nov 07 13:18:49 2017 -0500
@@ -5,6 +5,9 @@
> mq =
> [diff]
> nodates = 1
+ > [subrepos]
+ > allowed = true
+ > svn:allowed = true
> EOF
fn to create new repository, and cd into it
--- a/tests/test-subrepo-git.t Sat Oct 21 17:46:41 2017 +0900
+++ b/tests/test-subrepo-git.t Tue Nov 07 13:18:49 2017 -0500
@@ -41,7 +41,23 @@
$ echo 's = [git]../gitroot' > .hgsub
$ git clone -q ../gitroot s
$ hg add .hgsub
+
+git subrepo is disabled by default
+
$ hg commit -m 'new git subrepo'
+ abort: git subrepos not allowed
+ (see 'hg help config.subrepos' for details)
+ [255]
+
+so enable it
+
+ $ cat >> $HGRCPATH <<EOF
+ > [subrepos]
+ > git:allowed = true
+ > EOF
+
+ $ hg commit -m 'new git subrepo'
+
$ hg debugsub
path s
source ../gitroot
@@ -86,9 +102,29 @@
path s
source ../gitroot
revision 126f2a14290cd5ce061fdedc430170e8d39e1c5a
+ $ cd ..
+
+clone with subrepo disabled (update should fail)
+
+ $ hg clone t -U tc2 --config subrepos.allowed=false
+ $ hg update -R tc2 --config subrepos.allowed=false
+ abort: subrepos not enabled
+ (see 'hg help config.subrepos' for details)
+ [255]
+ $ ls tc2
+ a
+
+ $ hg clone t tc3 --config subrepos.allowed=false
+ updating to branch default
+ abort: subrepos not enabled
+ (see 'hg help config.subrepos' for details)
+ [255]
+ $ ls tc3
+ a
update to previous substate
+ $ cd tc
$ hg update 1 -q
$ cat s/g
g
@@ -400,11 +436,13 @@
Don't crash if subrepo is a broken symlink
$ ln -s broken s
$ hg status -S
+ abort: subrepo 's' traverses symbolic link
+ [255]
$ hg push -q
- abort: subrepo s is missing (in subrepository "s")
+ abort: subrepo 's' traverses symbolic link
[255]
$ hg commit --subrepos -qm missing
- abort: subrepo s is missing (in subrepository "s")
+ abort: subrepo 's' traverses symbolic link
[255]
$ rm s
#endif
--- a/tests/test-subrepo-svn.t Sat Oct 21 17:46:41 2017 +0900
+++ b/tests/test-subrepo-svn.t Tue Nov 07 13:18:49 2017 -0500
@@ -57,6 +57,21 @@
$ mkdir subdir
$ svn co --quiet "$SVNREPOURL"/src subdir/s
$ hg add .hgsub
+
+svn subrepo is disabled by default
+
+ $ hg ci -m1
+ abort: svn subrepos not allowed
+ (see 'hg help config.subrepos' for details)
+ [255]
+
+so enable it
+
+ $ cat >> $HGRCPATH <<EOF
+ > [subrepos]
+ > svn:allowed = true
+ > EOF
+
$ hg ci -m1
make sure we avoid empty commits (issue2445)
--- a/tests/test-subrepo.t Sat Oct 21 17:46:41 2017 +0900
+++ b/tests/test-subrepo.t Tue Nov 07 13:18:49 2017 -0500
@@ -484,9 +484,47 @@
path t
source t
revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
+ $ cd ..
+
+clone with subrepo disabled (update should fail)
+
+ $ hg clone t -U tc2 --config subrepos.allowed=false
+ $ hg update -R tc2 --config subrepos.allowed=false
+ abort: subrepos not enabled
+ (see 'hg help config.subrepos' for details)
+ [255]
+ $ ls tc2
+ a
+
+ $ hg clone t tc3 --config subrepos.allowed=false
+ updating to branch default
+ abort: subrepos not enabled
+ (see 'hg help config.subrepos' for details)
+ [255]
+ $ ls tc3
+ a
+
+And again with just the hg type disabled
+
+ $ hg clone t -U tc4 --config subrepos.hg:allowed=false
+ $ hg update -R tc4 --config subrepos.hg:allowed=false
+ abort: hg subrepos not allowed
+ (see 'hg help config.subrepos' for details)
+ [255]
+ $ ls tc4
+ a
+
+ $ hg clone t tc5 --config subrepos.hg:allowed=false
+ updating to branch default
+ abort: hg subrepos not allowed
+ (see 'hg help config.subrepos' for details)
+ [255]
+ $ ls tc5
+ a
push
+ $ cd tc
$ echo bah > t/t
$ hg ci -m11
committing subrepository t