26 def __init__(self, baseui, path=None, create=0): |
26 def __init__(self, baseui, path=None, create=0): |
27 repo.repository.__init__(self) |
27 repo.repository.__init__(self) |
28 self.root = os.path.realpath(util.expandpath(path)) |
28 self.root = os.path.realpath(util.expandpath(path)) |
29 self.path = os.path.join(self.root, ".hg") |
29 self.path = os.path.join(self.root, ".hg") |
30 self.origroot = path |
30 self.origroot = path |
|
31 self.auditor = util.path_auditor(self.root, self._checknested) |
31 self.opener = util.opener(self.path) |
32 self.opener = util.opener(self.path) |
32 self.wopener = util.opener(self.root) |
33 self.wopener = util.opener(self.root) |
33 self.baseui = baseui |
34 self.baseui = baseui |
34 self.ui = baseui.copy() |
35 self.ui = baseui.copy() |
35 |
36 |
108 self._branchcachetip = None |
109 self._branchcachetip = None |
109 self.nodetagscache = None |
110 self.nodetagscache = None |
110 self.filterpats = {} |
111 self.filterpats = {} |
111 self._datafilters = {} |
112 self._datafilters = {} |
112 self._transref = self._lockref = self._wlockref = None |
113 self._transref = self._lockref = self._wlockref = None |
|
114 |
|
115 def _checknested(self, path): |
|
116 """Determine if path is a legal nested repository.""" |
|
117 if not path.startswith(self.root): |
|
118 return False |
|
119 subpath = path[len(self.root) + 1:] |
|
120 |
|
121 # XXX: Checking against the current working copy is wrong in |
|
122 # the sense that it can reject things like |
|
123 # |
|
124 # $ hg cat -r 10 sub/x.txt |
|
125 # |
|
126 # if sub/ is no longer a subrepository in the working copy |
|
127 # parent revision. |
|
128 # |
|
129 # However, it can of course also allow things that would have |
|
130 # been rejected before, such as the above cat command if sub/ |
|
131 # is a subrepository now, but was a normal directory before. |
|
132 # The old path auditor would have rejected by mistake since it |
|
133 # panics when it sees sub/.hg/. |
|
134 # |
|
135 # All in all, checking against the working copy parent |
|
136 # revision seems sensible since we want to prevent access to |
|
137 # nested repositories on the filesystem *now*. |
|
138 ctx = self['.'] |
|
139 parts = util.splitpath(subpath) |
|
140 while parts: |
|
141 prefix = os.sep.join(parts) |
|
142 if prefix in ctx.substate: |
|
143 if prefix == subpath: |
|
144 return True |
|
145 else: |
|
146 sub = ctx.sub(prefix) |
|
147 return sub.checknested(subpath[len(prefix) + 1:]) |
|
148 else: |
|
149 parts.pop() |
|
150 return False |
|
151 |
113 |
152 |
114 @propertycache |
153 @propertycache |
115 def changelog(self): |
154 def changelog(self): |
116 c = changelog.changelog(self.sopener) |
155 c = changelog.changelog(self.sopener) |
117 if 'HG_PENDING' in os.environ: |
156 if 'HG_PENDING' in os.environ: |