diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py index 80d7dbda92940c49e0fd66230ae07cd526b3629c_bWVyY3VyaWFsL3N1YnJlcG8ucHk=..071cbeba421217d722a69a5d614ec934684d62d5_bWVyY3VyaWFsL3N1YnJlcG8ucHk= 100644 --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -359,6 +359,12 @@ "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) + 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,7 +375,7 @@ from . import hg as h hg = h - pathutil.pathauditor(ctx.repo().root)(path) + _auditsubrepopath(ctx.repo(), path) state = ctx.substate[path] if state[2] not in types: raise error.Abort(_('unknown subrepo type %s') % state[2]) @@ -387,7 +393,7 @@ from . import hg as h hg = h - pathutil.pathauditor(ctx.repo().root)(path) + _auditsubrepopath(ctx.repo(), path) state = ctx.substate[path] if state[2] not in types: raise error.Abort(_('unknown subrepo type %s') % state[2]) diff --git a/tests/test-audit-subrepo.t b/tests/test-audit-subrepo.t index 80d7dbda92940c49e0fd66230ae07cd526b3629c_dGVzdHMvdGVzdC1hdWRpdC1zdWJyZXBvLnQ=..071cbeba421217d722a69a5d614ec934684d62d5_dGVzdHMvdGVzdC1hdWRpdC1zdWJyZXBvLnQ= 100644 --- a/tests/test-audit-subrepo.t +++ b/tests/test-audit-subrepo.t @@ -50,5 +50,4 @@ $ hg ci -qAm 'add symlink "out"' $ hg init ../out $ echo 'out = out' >> .hgsub -BROKEN: should fail $ hg ci -qAm 'add subrepo "out"' @@ -54,6 +53,25 @@ $ 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 @@ -55,7 +73,6 @@ $ cd ../.. on clone (and update): $ mkdir hgsymdir2 -BROKEN: should fail to update $ hg clone -q hgsymdir/root hgsymdir2/root @@ -61,2 +78,4 @@ $ hg clone -q hgsymdir/root hgsymdir2/root + abort: subrepo 'out' traverses symbolic link + [255] $ ls hgsymdir2 @@ -62,5 +81,4 @@ $ ls hgsymdir2 - out root #endif diff --git a/tests/test-subrepo-git.t b/tests/test-subrepo-git.t index 80d7dbda92940c49e0fd66230ae07cd526b3629c_dGVzdHMvdGVzdC1zdWJyZXBvLWdpdC50..071cbeba421217d722a69a5d614ec934684d62d5_dGVzdHMvdGVzdC1zdWJyZXBvLWdpdC50 100644 --- a/tests/test-subrepo-git.t +++ b/tests/test-subrepo-git.t @@ -400,4 +400,6 @@ 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 @@ -403,4 +405,4 @@ $ hg push -q - abort: subrepo s is missing (in subrepository "s") + abort: subrepo 's' traverses symbolic link [255] $ hg commit --subrepos -qm missing @@ -405,6 +407,6 @@ [255] $ hg commit --subrepos -qm missing - abort: subrepo s is missing (in subrepository "s") + abort: subrepo 's' traverses symbolic link [255] $ rm s #endif