Mercurial > hgsubversion
comparison hgsubversion/svnexternals.py @ 1352:30193fdd5da4
Addressed using relative URLs to actually divert to another server & added DocTest strings.
Code has been tested on real-world repositories that use relative references
but adding tests which do the round trip testing as a standalone has been beyond
me.
author | Gadget Steve <gadgetsteve@hotmail.com> |
---|---|
date | Sat, 19 Sep 2015 07:27:31 +0100 |
parents | 9d58ca6253a3 |
children | c79fdd5f615d |
comparison
equal
deleted
inserted
replaced
1351:9d58ca6253a3 | 1352:30193fdd5da4 |
---|---|
123 def resolvedots(url): | 123 def resolvedots(url): |
124 """ | 124 """ |
125 Fix references that include .. entries. | 125 Fix references that include .. entries. |
126 Scans a URL for .. type entries and resolves them but will not allow any | 126 Scans a URL for .. type entries and resolves them but will not allow any |
127 number of ..s to take us out of domain so http://.. will raise an exception. | 127 number of ..s to take us out of domain so http://.. will raise an exception. |
128 | |
129 Tests, (Don't know how to construct a round trip for this so doctest): | |
130 >>> # Relative URL within servers svn area | |
131 >>> resolvedots( | |
132 ... "http://some.svn.server/svn/some_repo/../other_repo") | |
133 'http://some.svn.server/svn/other_repo' | |
134 >>> # Complex One | |
135 >>> resolvedots( | |
136 ... "http://some.svn.server/svn/repo/../other/repo/../../other_repo") | |
137 'http://some.svn.server/svn/other_repo' | |
138 >>> # Another Complex One | |
139 >>> resolvedots( | |
140 ... "http://some.svn.server/svn/repo/dir/subdir/../../../other_repo/dir") | |
141 'http://some.svn.server/svn/other_repo/dir' | |
142 >>> # Last Complex One - SVN Allows this & seen it used even if it is BAD! | |
143 >>> resolvedots( | |
144 ... "http://svn.server/svn/my_repo/dir/subdir/../../other_dir") | |
145 'http://svn.server/svn/my_repo/other_dir' | |
146 >>> # Outside the SVN Area might be OK | |
147 >>> resolvedots( | |
148 ... "http://svn.server/svn/some_repo/../../other_svn_repo") | |
149 'http://svn.server/other_svn_repo' | |
150 >>> # Complex One | |
151 >>> resolvedots( | |
152 ... "http://some.svn.server/svn/repo/../other/repo/../../other_repo") | |
153 'http://some.svn.server/svn/other_repo' | |
154 >>> # On another server is not a relative URL should give an exception | |
155 >>> resolvedots( | |
156 ... "http://some.svn.server/svn/some_repo/../../../other_server") | |
157 Traceback (most recent call last): | |
158 ... | |
159 RelativeSourceError: Relative URL cannot be to another server | |
128 """ | 160 """ |
129 orig = url.split('/') | 161 orig = url.split('/') |
130 fixed = [] | 162 fixed = [] |
131 for item in orig: | 163 for item in orig: |
132 if item != '..': | 164 if item != '..': |
133 fixed.append(item) | 165 fixed.append(item) |
134 elif len(fixed) > 2: # Don't allow things to go out of domain | 166 elif len(fixed) > 3: # Don't allow things to go out of domain |
135 fixed.pop() | 167 fixed.pop() |
136 else: | 168 else: |
137 raise RelativeSourceError() | 169 raise RelativeSourceError( |
170 'Relative URL cannot be to another server') | |
138 return '/'.join(fixed) | 171 return '/'.join(fixed) |
139 | 172 |
173 | |
174 | |
140 def resolvesource(ui, svnroot, source): | 175 def resolvesource(ui, svnroot, source): |
176 """ Resolve the source as either matching the scheme re or by resolving | |
177 relative URLs which start with ^ and my include relative .. references. | |
178 | |
179 >>> root = 'http://some.svn.server/svn/some_repo' | |
180 >>> resolvesource(None, root, 'http://other.svn.server') | |
181 'http://other.svn.server' | |
182 >>> resolvesource(None, root, 'ssh://other.svn.server') | |
183 'ssh://other.svn.server' | |
184 >>> resolvesource(None, root, '^/other_repo') | |
185 'http://some.svn.server/svn/some_repo/other_repo' | |
186 >>> resolvesource(None, root, '^/sub_repo') | |
187 'http://some.svn.server/svn/some_repo/sub_repo' | |
188 >>> resolvesource(None, root, '^/../other_repo') | |
189 'http://some.svn.server/svn/other_repo' | |
190 >>> resolvesource(None, root, '^/../../../server/other_repo') | |
191 Traceback (most recent call last): | |
192 ... | |
193 RelativeSourceError: Relative URL cannot be to another server | |
194 """ | |
141 if re_scheme.search(source): | 195 if re_scheme.search(source): |
142 return source | 196 return source |
143 if source.startswith('^/'): | 197 if source.startswith('^/'): |
144 if svnroot is None: | 198 if svnroot is None: |
145 raise RelativeSourceError() | 199 raise RelativeSourceError() |
455 def basestate(self): | 509 def basestate(self): |
456 # basestate() was introduced by bcb973abcc0b in 2.2 | 510 # basestate() was introduced by bcb973abcc0b in 2.2 |
457 if self._state[1] == 'HEAD': | 511 if self._state[1] == 'HEAD': |
458 return 'HEAD' | 512 return 'HEAD' |
459 return super(svnsubrepo, self).basestate() | 513 return super(svnsubrepo, self).basestate() |
514 | |
515 if __name__ == "__main__": | |
516 import doctest | |
517 doctest.testmod() |