Show More
@@ -197,3 +197,4 b' 8fca7e8449a847e3cf1054f2c07b51237699fad3' | |||||
197 | 26ce8e7515036d3431a03aaeb7bc72dd96cb1112 0 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 |
@@ -210,3 +210,4 b' 8fca7e8449a847e3cf1054f2c07b51237699fad3' | |||||
210 | 26ce8e7515036d3431a03aaeb7bc72dd96cb1112 5.4rc0 |
|
210 | 26ce8e7515036d3431a03aaeb7bc72dd96cb1112 5.4rc0 | |
211 | cf3e07d7648a4371ce584d15dd692e7a6845792f 5.4 |
|
211 | cf3e07d7648a4371ce584d15dd692e7a6845792f 5.4 | |
212 | 065704cbdbdbb05dcd6bb814eb9bbdd982211b28 5.4.1 |
|
212 | 065704cbdbdbb05dcd6bb814eb9bbdd982211b28 5.4.1 | |
|
213 | 0ea9c86fac8974cd74dc12ea681c8986eb6da6c4 5.4.2 |
@@ -3,6 +3,8 b'' | |||||
3 | # Copyright(C) 2007 Daniel Holth et al |
|
3 | # Copyright(C) 2007 Daniel Holth et al | |
4 | from __future__ import absolute_import |
|
4 | from __future__ import absolute_import | |
5 |
|
5 | |||
|
6 | import codecs | |||
|
7 | import locale | |||
6 | import os |
|
8 | import os | |
7 | import re |
|
9 | import re | |
8 | import xml.dom.minidom |
|
10 | import xml.dom.minidom | |
@@ -63,6 +65,38 b' except ImportError:' | |||||
63 | svn = None |
|
65 | svn = None | |
64 |
|
66 | |||
65 |
|
67 | |||
|
68 | # In Subversion, paths and URLs are Unicode (encoded as UTF-8), which | |||
|
69 | # Subversion converts from / to native strings when interfacing with the OS. | |||
|
70 | # When passing paths and URLs to Subversion, we have to recode them such that | |||
|
71 | # it roundstrips with what Subversion is doing. | |||
|
72 | ||||
|
73 | fsencoding = None | |||
|
74 | ||||
|
75 | ||||
|
76 | def init_fsencoding(): | |||
|
77 | global fsencoding, fsencoding_is_utf8 | |||
|
78 | if fsencoding is not None: | |||
|
79 | return | |||
|
80 | if pycompat.iswindows: | |||
|
81 | # On Windows, filenames are Unicode, but we store them using the MBCS | |||
|
82 | # encoding. | |||
|
83 | fsencoding = 'mbcs' | |||
|
84 | else: | |||
|
85 | # This is the encoding used to convert UTF-8 back to natively-encoded | |||
|
86 | # strings in Subversion 1.14.0 or earlier with APR 1.7.0 or earlier. | |||
|
87 | with util.with_lc_ctype(): | |||
|
88 | fsencoding = locale.nl_langinfo(locale.CODESET) or 'ISO-8859-1' | |||
|
89 | fsencoding = codecs.lookup(fsencoding).name | |||
|
90 | fsencoding_is_utf8 = fsencoding == codecs.lookup('utf-8').name | |||
|
91 | ||||
|
92 | ||||
|
93 | def fs2svn(s): | |||
|
94 | if fsencoding_is_utf8: | |||
|
95 | return s | |||
|
96 | else: | |||
|
97 | return s.decode(fsencoding).encode('utf-8') | |||
|
98 | ||||
|
99 | ||||
66 | class SvnPathNotFound(Exception): |
|
100 | class SvnPathNotFound(Exception): | |
67 | pass |
|
101 | pass | |
68 |
|
102 | |||
@@ -106,8 +140,15 b' def quote(s):' | |||||
106 |
|
140 | |||
107 |
|
141 | |||
108 | def geturl(path): |
|
142 | def geturl(path): | |
|
143 | """Convert path or URL to a SVN URL, encoded in UTF-8. | |||
|
144 | ||||
|
145 | This can raise UnicodeDecodeError if the path or URL can't be converted to | |||
|
146 | unicode using `fsencoding`. | |||
|
147 | """ | |||
109 | try: |
|
148 | try: | |
110 |
return svn.client.url_from_path( |
|
149 | return svn.client.url_from_path( | |
|
150 | svn.core.svn_path_canonicalize(fs2svn(path)) | |||
|
151 | ) | |||
111 | except svn.core.SubversionException: |
|
152 | except svn.core.SubversionException: | |
112 | # svn.client.url_from_path() fails with local repositories |
|
153 | # svn.client.url_from_path() fails with local repositories | |
113 | pass |
|
154 | pass | |
@@ -117,7 +158,7 b' def geturl(path):' | |||||
117 | path = b'/' + util.normpath(path) |
|
158 | path = b'/' + util.normpath(path) | |
118 | # Module URL is later compared with the repository URL returned |
|
159 | # Module URL is later compared with the repository URL returned | |
119 | # by svn API, which is UTF-8. |
|
160 | # by svn API, which is UTF-8. | |
120 |
path = |
|
161 | path = fs2svn(path) | |
121 | path = b'file://%s' % quote(path) |
|
162 | path = b'file://%s' % quote(path) | |
122 | return svn.core.svn_path_canonicalize(path) |
|
163 | return svn.core.svn_path_canonicalize(path) | |
123 |
|
164 | |||
@@ -284,7 +325,9 b' def filecheck(ui, path, proto):' | |||||
284 | def httpcheck(ui, path, proto): |
|
325 | def httpcheck(ui, path, proto): | |
285 | try: |
|
326 | try: | |
286 | opener = urlreq.buildopener() |
|
327 | opener = urlreq.buildopener() | |
287 | rsp = opener.open(b'%s://%s/!svn/ver/0/.svn' % (proto, path), b'rb') |
|
328 | rsp = opener.open( | |
|
329 | pycompat.strurl(b'%s://%s/!svn/ver/0/.svn' % (proto, path)), b'rb' | |||
|
330 | ) | |||
288 | data = rsp.read() |
|
331 | data = rsp.read() | |
289 | except urlerr.httperror as inst: |
|
332 | except urlerr.httperror as inst: | |
290 | if inst.code != 404: |
|
333 | if inst.code != 404: | |
@@ -311,6 +354,32 b' protomap = {' | |||||
311 | } |
|
354 | } | |
312 |
|
355 | |||
313 |
|
356 | |||
|
357 | class NonUtf8PercentEncodedBytes(Exception): | |||
|
358 | pass | |||
|
359 | ||||
|
360 | ||||
|
361 | # Subversion paths are Unicode. Since the percent-decoding is done on | |||
|
362 | # UTF-8-encoded strings, percent-encoded bytes are interpreted as UTF-8. | |||
|
363 | def url2pathname_like_subversion(unicodepath): | |||
|
364 | if pycompat.ispy3: | |||
|
365 | # On Python 3, we have to pass unicode to urlreq.url2pathname(). | |||
|
366 | # Percent-decoded bytes get decoded using UTF-8 and the 'replace' error | |||
|
367 | # handler. | |||
|
368 | unicodepath = urlreq.url2pathname(unicodepath) | |||
|
369 | if u'\N{REPLACEMENT CHARACTER}' in unicodepath: | |||
|
370 | raise NonUtf8PercentEncodedBytes | |||
|
371 | else: | |||
|
372 | return unicodepath | |||
|
373 | else: | |||
|
374 | # If we passed unicode on Python 2, it would be converted using the | |||
|
375 | # latin-1 encoding. Therefore, we pass UTF-8-encoded bytes. | |||
|
376 | unicodepath = urlreq.url2pathname(unicodepath.encode('utf-8')) | |||
|
377 | try: | |||
|
378 | return unicodepath.decode('utf-8') | |||
|
379 | except UnicodeDecodeError: | |||
|
380 | raise NonUtf8PercentEncodedBytes | |||
|
381 | ||||
|
382 | ||||
314 | def issvnurl(ui, url): |
|
383 | def issvnurl(ui, url): | |
315 | try: |
|
384 | try: | |
316 | proto, path = url.split(b'://', 1) |
|
385 | proto, path = url.split(b'://', 1) | |
@@ -322,31 +391,58 b' def issvnurl(ui, url):' | |||||
322 | and path[2:6].lower() == b'%3a/' |
|
391 | and path[2:6].lower() == b'%3a/' | |
323 | ): |
|
392 | ): | |
324 | path = path[:2] + b':/' + path[6:] |
|
393 | path = path[:2] + b':/' + path[6:] | |
325 | # pycompat.fsdecode() / pycompat.fsencode() are used so that bytes |
|
394 | try: | |
326 | # in the URL roundtrip correctly on Unix. urlreq.url2pathname() on |
|
395 | unicodepath = path.decode(fsencoding) | |
327 | # py3 will decode percent-encoded bytes using the utf-8 encoding |
|
396 | except UnicodeDecodeError: | |
328 | # and the "replace" error handler. This means that it will not |
|
|||
329 | # preserve non-UTF-8 bytes (https://bugs.python.org/issue40983). |
|
|||
330 | # url.open() uses the reverse function (urlreq.pathname2url()) and |
|
|||
331 | # has a similar problem |
|
|||
332 | # (https://bz.mercurial-scm.org/show_bug.cgi?id=6357). It makes |
|
|||
333 | # sense to solve both problems together and handle all file URLs |
|
|||
334 | # consistently. For now, we warn. |
|
|||
335 | unicodepath = urlreq.url2pathname(pycompat.fsdecode(path)) |
|
|||
336 | if pycompat.ispy3 and u'\N{REPLACEMENT CHARACTER}' in unicodepath: |
|
|||
337 | ui.warn( |
|
397 | ui.warn( | |
338 | _( |
|
398 | _( | |
339 | b'on Python 3, we currently do not support non-UTF-8 ' |
|
399 | b'Subversion requires that file URLs can be converted ' | |
340 | b'percent-encoded bytes in file URLs for Subversion ' |
|
400 | b'to Unicode using the current locale encoding (%s)\n' | |
341 |
|
|
401 | ) | |
|
402 | % pycompat.sysbytes(fsencoding) | |||
|
403 | ) | |||
|
404 | return False | |||
|
405 | try: | |||
|
406 | unicodepath = url2pathname_like_subversion(unicodepath) | |||
|
407 | except NonUtf8PercentEncodedBytes: | |||
|
408 | ui.warn( | |||
|
409 | _( | |||
|
410 | b'Subversion does not support non-UTF-8 ' | |||
|
411 | b'percent-encoded bytes in file URLs\n' | |||
342 | ) |
|
412 | ) | |
343 | ) |
|
413 | ) | |
344 | path = pycompat.fsencode(unicodepath) |
|
414 | return False | |
|
415 | # Below, we approximate how Subversion checks the path. On Unix, we | |||
|
416 | # should therefore convert the path to bytes using `fsencoding` | |||
|
417 | # (like Subversion does). On Windows, the right thing would | |||
|
418 | # actually be to leave the path as unicode. For now, we restrict | |||
|
419 | # the path to MBCS. | |||
|
420 | path = unicodepath.encode(fsencoding) | |||
345 | except ValueError: |
|
421 | except ValueError: | |
346 | proto = b'file' |
|
422 | proto = b'file' | |
347 | path = os.path.abspath(url) |
|
423 | path = os.path.abspath(url) | |
|
424 | try: | |||
|
425 | path.decode(fsencoding) | |||
|
426 | except UnicodeDecodeError: | |||
|
427 | ui.warn( | |||
|
428 | _( | |||
|
429 | b'Subversion requires that paths can be converted to ' | |||
|
430 | b'Unicode using the current locale encoding (%s)\n' | |||
|
431 | ) | |||
|
432 | % pycompat.sysbytes(fsencoding) | |||
|
433 | ) | |||
|
434 | return False | |||
348 | if proto == b'file': |
|
435 | if proto == b'file': | |
349 | path = util.pconvert(path) |
|
436 | path = util.pconvert(path) | |
|
437 | elif proto in (b'http', 'https'): | |||
|
438 | if not encoding.isasciistr(path): | |||
|
439 | ui.warn( | |||
|
440 | _( | |||
|
441 | b"Subversion sources don't support non-ASCII characters in " | |||
|
442 | b"HTTP(S) URLs. Please percent-encode them.\n" | |||
|
443 | ) | |||
|
444 | ) | |||
|
445 | return False | |||
350 | check = protomap.get(proto, lambda *args: False) |
|
446 | check = protomap.get(proto, lambda *args: False) | |
351 | while b'/' in path: |
|
447 | while b'/' in path: | |
352 | if check(ui, path, proto): |
|
448 | if check(ui, path, proto): | |
@@ -373,6 +469,7 b' class svn_source(converter_source):' | |||||
373 | def __init__(self, ui, repotype, url, revs=None): |
|
469 | def __init__(self, ui, repotype, url, revs=None): | |
374 | super(svn_source, self).__init__(ui, repotype, url, revs=revs) |
|
470 | super(svn_source, self).__init__(ui, repotype, url, revs=revs) | |
375 |
|
471 | |||
|
472 | init_fsencoding() | |||
376 | if not ( |
|
473 | if not ( | |
377 | url.startswith(b'svn://') |
|
474 | url.startswith(b'svn://') | |
378 | or url.startswith(b'svn+ssh://') |
|
475 | or url.startswith(b'svn+ssh://') |
@@ -153,22 +153,65 b' Check tags are in UTF-8' | |||||
153 |
|
153 | |||
154 | $ cd .. |
|
154 | $ cd .. | |
155 |
|
155 | |||
156 | #if py3 |
|
156 | Subversion sources don't support non-ASCII characters in HTTP(S) URLs. | |
157 | For now, on Python 3, we abort when encountering non-UTF-8 percent-encoded |
|
157 | ||
158 | bytes in a filename. |
|
158 | $ XFF=$($PYTHON -c 'from mercurial.utils.procutil import stdout; stdout.write(b"\xff")') | |
|
159 | $ hg convert --source-type=svn http://localhost:$HGPORT/$XFF test | |||
|
160 | initializing destination test repository | |||
|
161 | Subversion sources don't support non-ASCII characters in HTTP(S) URLs. Please percent-encode them. | |||
|
162 | http://localhost:$HGPORT/\xff does not look like a Subversion repository (esc) | |||
|
163 | abort: http://localhost:$HGPORT/\xff: missing or unsupported repository (esc) | |||
|
164 | [255] | |||
|
165 | ||||
|
166 | In Subversion, paths are Unicode (encoded as UTF-8). Therefore paths that can't | |||
|
167 | be converted between UTF-8 and the locale encoding (which is always ASCII in | |||
|
168 | tests) don't work. | |||
159 |
|
169 | |||
160 | $ hg convert file:///%ff test |
|
170 | $ cp -R svn-repo $XFF | |
|
171 | $ hg convert $XFF test | |||
|
172 | initializing destination test repository | |||
|
173 | Subversion requires that paths can be converted to Unicode using the current locale encoding (ascii) | |||
|
174 | \xff does not look like a CVS checkout (glob) (esc) | |||
|
175 | $TESTTMP/\xff does not look like a Git repository (esc) | |||
|
176 | \xff does not look like a Subversion repository (glob) (esc) | |||
|
177 | \xff is not a local Mercurial repository (glob) (esc) | |||
|
178 | \xff does not look like a darcs repository (glob) (esc) | |||
|
179 | \xff does not look like a monotone repository (glob) (esc) | |||
|
180 | \xff does not look like a GNU Arch repository (glob) (esc) | |||
|
181 | \xff does not look like a Bazaar repository (glob) (esc) | |||
|
182 | cannot find required "p4" tool | |||
|
183 | abort: \xff: missing or unsupported repository (glob) (esc) | |||
|
184 | [255] | |||
|
185 | $ hg convert file://$TESTTMP/$XFF test | |||
161 | initializing destination test repository |
|
186 | initializing destination test repository | |
162 | on Python 3, we currently do not support non-UTF-8 percent-encoded bytes in file URLs for Subversion repositories |
|
187 | Subversion requires that file URLs can be converted to Unicode using the current locale encoding (ascii) | |
163 |
file:/ |
|
188 | file:/*/$TESTTMP/\xff does not look like a CVS checkout (glob) (esc) | |
164 |
$TESTTMP/file: |
|
189 | $TESTTMP/file:$TESTTMP/\xff does not look like a Git repository (esc) | |
165 |
file:/ |
|
190 | file:/*/$TESTTMP/\xff does not look like a Subversion repository (glob) (esc) | |
166 |
file:/ |
|
191 | file:/*/$TESTTMP/\xff is not a local Mercurial repository (glob) (esc) | |
167 |
file:/ |
|
192 | file:/*/$TESTTMP/\xff does not look like a darcs repository (glob) (esc) | |
168 |
file:/ |
|
193 | file:/*/$TESTTMP/\xff does not look like a monotone repository (glob) (esc) | |
169 |
file:/ |
|
194 | file:/*/$TESTTMP/\xff does not look like a GNU Arch repository (glob) (esc) | |
170 |
file:/ |
|
195 | file:/*/$TESTTMP/\xff does not look like a Bazaar repository (glob) (esc) | |
171 |
file:/ |
|
196 | file:/*/$TESTTMP/\xff does not look like a P4 repository (glob) (esc) | |
172 |
abort: file:/ |
|
197 | abort: file:/*/$TESTTMP/\xff: missing or unsupported repository (glob) (esc) | |
173 | [255] |
|
198 | [255] | |
174 | #endif |
|
199 | ||
|
200 | Subversion decodes percent-encoded bytes on the converted, UTF-8-encoded | |||
|
201 | string. Therefore, if the percent-encoded bytes aren't valid UTF-8, Subversion | |||
|
202 | would choke on them when converting them to the locale encoding. | |||
|
203 | ||||
|
204 | $ hg convert file://$TESTTMP/%FF test | |||
|
205 | initializing destination test repository | |||
|
206 | Subversion does not support non-UTF-8 percent-encoded bytes in file URLs | |||
|
207 | file:/*/$TESTTMP/%FF does not look like a CVS checkout (glob) | |||
|
208 | $TESTTMP/file:$TESTTMP/%FF does not look like a Git repository | |||
|
209 | file:/*/$TESTTMP/%FF does not look like a Subversion repository (glob) | |||
|
210 | file:/*/$TESTTMP/%FF is not a local Mercurial repository (glob) | |||
|
211 | file:/*/$TESTTMP/%FF does not look like a darcs repository (glob) | |||
|
212 | file:/*/$TESTTMP/%FF does not look like a monotone repository (glob) | |||
|
213 | file:/*/$TESTTMP/%FF does not look like a GNU Arch repository (glob) | |||
|
214 | file:/*/$TESTTMP/%FF does not look like a Bazaar repository (glob) | |||
|
215 | file:/*/$TESTTMP/%FF does not look like a P4 repository (glob) | |||
|
216 | abort: file:/*/$TESTTMP/%FF: missing or unsupported repository (glob) | |||
|
217 | [255] |
General Comments 0
You need to be logged in to leave comments.
Login now