File hg-subrepo-bsc1071715-fix02.patch of Package mercurial.8018

# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1509707570 -32400
#      Fri Nov 03 20:12:50 2017 +0900
# Branch stable
# Node ID 071cbeba421217d722a69a5d614ec934684d62d5
# Parent  80d7dbda92940c49e0fd66230ae07cd526b3629c
subrepo: disallow symlink traversal across subrepo mount point (SEC)

It wasn't easy to extend the pathauditor to check symlink traversal across
subrepos because pathauditor._checkfs() rejects a directory having ".hg"
directory. That's why I added the explicit islink() check.

No idea if this patch is necessary after we've fixed the issue5730 by
splitting submerge() into planning and execution phases.

---
 mercurial/subrepo.py       |    8 +++++++-
 tests/test-audit-subrepo.t |   24 +++++++++++++++++++++---
 tests/test-subrepo-git.t   |   14 ++++++++++++++
 3 files changed, 42 insertions(+), 4 deletions(-)

--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -334,6 +334,12 @@ def itersubrepos(ctx1, ctx2):
     for subpath, ctx in sorted(subpaths.iteritems()):
         yield subpath, ctx.sub(subpath)
 
+def _auditsubrepopath(repo, path):
+    # auditor doesn't check if the path itself is a symlink
+    scmutil.pathauditor(repo.root)(path)
+    if repo.wvfs.islink(path):
+        raise error.Abort(_("subrepo '%s' traverses symbolic link") % path)
+
 def subrepo(ctx, path):
     """return instance of the right subrepo class for subrepo in path"""
     # subrepo inherently violates our import layering rules
@@ -344,7 +350,7 @@ def subrepo(ctx, path):
     import hg as h
     hg = h
 
-    scmutil.pathauditor(ctx._repo.root)(path)
+    _auditsubrepopath(ctx._repo, path)
     state = ctx.substate[path]
     if state[2] not in types:
         raise util.Abort(_('unknown subrepo type %s') % state[2])
--- a/tests/test-audit-subrepo.t
+++ b/tests/test-audit-subrepo.t
@@ -50,17 +50,35 @@ on commit:
   $ hg ci -qAm 'add symlink "out"'
   $ hg init ../out
   $ echo 'out = out' >> .hgsub
-BROKEN: should fail
   $ 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
-BROKEN: should fail to update
   $ hg clone -q hgsymdir/root hgsymdir2/root
+  abort: subrepo 'out' traverses symbolic link
+  [255]
   $ ls hgsymdir2
-  out
   root
 
 #endif
--- a/tests/test-subrepo-git.t
+++ b/tests/test-subrepo-git.t
@@ -364,6 +364,20 @@ Don't crash if the subrepo is missing
   $ hg commit --subrepos -qm missing
   abort: subrepo s is missing (in subrepo s)
   [255]
+
+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' traverses symbolic link
+  [255]
+  $ hg commit --subrepos -qm missing
+  abort: subrepo 's' traverses symbolic link
+  [255]
+  $ rm s
+
   $ hg update -C 2> /dev/null
   cloning subrepo s from $TESTTMP/gitroot
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
openSUSE Build Service is sponsored by