[MERGE] Fix handling of unicode paths in smart server requests
Andrew Bennetts
andrew at canonical.com
Thu Oct 12 11:49:04 BST 2006
http://people.ubuntu.com/~andrew/bzr/smart-server-unicode/ contains tests and
fixes for handling of unicode paths in smart server requests. There's some
double-handling (UTF-8 read off the wire gets decoded, then re-encoded), but at
least it's correct.
I haven't tested handling of non-ascii paths in responses yet, so I assume they
are broken! I'll take a look and add tests and if necessary fixes soon, but
this branch is already useful as is.
The branch is against http://people.ubuntu.com/~andrew/bzr/http-smart-server/,
because it builds on the refactoring that occurred in that branch.
I've attached a bundle relative to that branch for review.
-Andrew.
-------------- next part --------------
# Bazaar revision bundle v0.8
#
# message:
# Add a NEWS entry for this fix.
# committer: Andrew Bennetts <andrew.bennetts at canonical.com>
# date: Thu 2006-10-12 18:59:43.742000103 +1000
=== modified file NEWS
--- NEWS
+++ NEWS
@@ -39,6 +39,9 @@
* diff3 does not indicate conflicts on clean merge. (Aaron Bentley)
+ * The smart server now dispatches commands with non-ascii paths correctly.
+ (Andrew Bennetts)
+
TESTING:
* New test base class TestCaseWithMemoryTransport offers memory-only
=== modified file bzrlib/tests/test_smart_transport.py // last-changed:andrew.b
... ennetts at canonical.com-20061012085801-36b60463388ea0e7
--- bzrlib/tests/test_smart_transport.py
+++ bzrlib/tests/test_smart_transport.py
@@ -596,7 +596,7 @@
self.assertEqual('ok\0011\n',
from_server.getvalue())
- def test_canned_get_response(self):
+ def test_response_to_canned_get(self):
transport = memory.MemoryTransport('memory:///')
transport.put_bytes('testfile', 'contents\nof\nfile\n')
to_server = StringIO('get\001./testfile\n')
@@ -612,6 +612,24 @@
'done\n',
from_server.getvalue())
+ def test_response_to_canned_get_of_utf8(self):
+ # wire-to-wire, using the whole stack, with a UTF-8 filename.
+ transport = memory.MemoryTransport('memory:///')
+ utf8_filename = u'testfile\N{INTERROBANG}'.encode('utf-8')
+ transport.put_bytes(utf8_filename, 'contents\nof\nfile\n')
+ to_server = StringIO('get\001' + utf8_filename + '\n')
+ from_server = StringIO()
+ server = smart.SmartServerPipeStreamMedium(
+ to_server, from_server, transport)
+ protocol = smart.SmartServerRequestProtocolOne(transport,
+ from_server.write)
+ server._serve_one_request(protocol)
+ self.assertEqual('ok\n'
+ '17\n'
+ 'contents\nof\nfile\n'
+ 'done\n',
+ from_server.getvalue())
+
def test_pipe_like_stream_with_bulk_data(self):
sample_request_bytes = 'command\n9\nbulk datadone\n'
to_server = StringIO(sample_request_bytes)
@@ -933,7 +951,7 @@
def test_put_bytes_non_atomic(self):
"""'put_...' should set finished_reading after reading the bytes."""
handler = smart.SmartServerRequestHandler(self.get_transport())
- handler.dispatch_command('put_non_atomic', ('a-file', '', 'F', ''))
+ handler.dispatch_command('put_non_atomic', (u'a-file', u'', u'F', u''))
self.assertFalse(handler.finished_reading)
handler.accept_body('1234')
self.assertFalse(handler.finished_reading)
@@ -947,7 +965,7 @@
"""'readv' should set finished_reading after reading offsets."""
self.build_tree(['a-file'])
handler = smart.SmartServerRequestHandler(self.get_readonly_transport())
- handler.dispatch_command('readv', ('a-file', ))
+ handler.dispatch_command('readv', (u'a-file', ))
self.assertFalse(handler.finished_reading)
handler.accept_body('2,')
self.assertFalse(handler.finished_reading)
@@ -962,7 +980,7 @@
"""'readv' when a short read occurs sets the response appropriately."""
self.build_tree(['a-file'])
handler = smart.SmartServerRequestHandler(self.get_readonly_transport())
- handler.dispatch_command('readv', ('a-file', ))
+ handler.dispatch_command('readv', (u'a-file', ))
# read beyond the end of the file.
handler.accept_body('100,1')
handler.end_of_body()
@@ -972,6 +990,132 @@
self.assertEqual(None, handler.response.body)
+class SmartServerRequestHandlerUnicodeTests(tests.TestCaseWithTransport):
+ """Test unicode relpaths passed to the request handler.
+
+ SmartServerRequestProtocolOne decodes requests into a tuple of unicode
+ objects. That tuple is then passed to the request handler's
+ dispatch_command method. This test case is for testing that unicode paths
+ are handled correctly by the request handler.
+ """
+
+ def test_get_file(self):
+ self.build_tree([u'\N{INTERROBANG}'], line_endings='binary')
+ handler = smart.SmartServerRequestHandler(self.get_readonly_transport())
+ handler.dispatch_command('get', (u'\N{INTERROBANG}',))
+ self.assertEqual(('ok',), handler.response.args)
+ self.assertEqual(
+ u'contents of \N{INTERROBANG}\n'.encode('utf-8'),
+ handler.response.body)
+
+ def test_has(self):
+ self.build_tree([u'\N{INTERROBANG}'])
+ handler = smart.SmartServerRequestHandler(self.get_readonly_transport())
+ handler.dispatch_command('has', (u'\N{INTERROBANG}',))
+ self.assertEqual(('yes',), handler.response.args)
+
+ def test_append(self):
+ handler = smart.SmartServerRequestHandler(self.get_transport())
+ handler.dispatch_command('append', (u'\N{INTERROBANG}', ''))
+ handler.accept_body('abc\n')
+ handler.end_of_body()
+ self.assertEqual(('appended', '0'), handler.response.args)
+ self.check_file_contents(u'\N{INTERROBANG}'.encode('utf-8'), 'abc\n')
+
+ def test_delete(self):
+ self.build_tree([u'\N{INTERROBANG}'])
+ handler = smart.SmartServerRequestHandler(self.get_transport())
+ handler.dispatch_command('delete', (u'\N{INTERROBANG}',))
+ self.assertEqual(('ok',), handler.response.args)
+ self.failIfExists(u'\N{INTERROBANG}'.encode('utf-8'))
+
+ def test_iter_files_recursive(self):
+ self.build_tree([
+ u'\N{INTERROBANG}/',
+ u'\N{INTERROBANG}/one',
+ u'\N{INTERROBANG}/two',
+ ])
+ handler = smart.SmartServerRequestHandler(self.get_readonly_transport())
+ handler.dispatch_command('iter_files_recursive', (u'\N{INTERROBANG}',))
+ self.assertEqual('names', handler.response.args[0])
+ self.assertEqual(set(['one', 'two']), set(handler.response.args[1:]))
+
+ def test_list_dir(self):
+ self.build_tree([
+ u'\N{INTERROBANG}/',
+ u'\N{INTERROBANG}/one',
+ u'\N{INTERROBANG}/two',
+ ])
+ handler = smart.SmartServerRequestHandler(self.get_readonly_transport())
+ handler.dispatch_command('list_dir', (u'\N{INTERROBANG}',))
+ self.assertEqual('names', handler.response.args[0])
+ self.assertEqual(set(['one', 'two']), set(handler.response.args[1:]))
+
+ def test_mkdir(self):
+ handler = smart.SmartServerRequestHandler(self.get_transport())
+ handler.dispatch_command('mkdir', (u'\N{INTERROBANG}', ''))
+ self.assertEqual(('ok',), handler.response.args)
+ self.failUnlessExists(u'\N{INTERROBANG}'.encode('utf-8'))
+
+ def test_move(self):
+ self.build_tree([u'one\N{INTERROBANG}'])
+ handler = smart.SmartServerRequestHandler(self.get_transport())
+ handler.dispatch_command(
+ 'move', (u'one\N{INTERROBANG}', u'two\N{INTERROBANG}',))
+ self.assertEqual(('ok',), handler.response.args)
+ self.failIfExists(u'one\N{INTERROBANG}'.encode('utf-8'))
+ self.failUnlessExists(u'two\N{INTERROBANG}'.encode('utf-8'))
+
+ def test_put(self):
+ handler = smart.SmartServerRequestHandler(self.get_transport())
+ handler.dispatch_command('put', (u'\N{INTERROBANG}', ''))
+ handler.accept_body('abc\n')
+ handler.end_of_body()
+ self.assertEqual(('ok',), handler.response.args)
+ self.check_file_contents(u'\N{INTERROBANG}'.encode('utf-8'), 'abc\n')
+
+ def test_put_non_atomic(self):
+ handler = smart.SmartServerRequestHandler(self.get_transport())
+ handler.dispatch_command(
+ 'put_non_atomic', (u'\N{INTERROBANG}', '', 'F', ''))
+ handler.accept_body('abc\n')
+ handler.end_of_body()
+ self.assertEqual(('ok',), handler.response.args)
+ self.check_file_contents(u'\N{INTERROBANG}'.encode('utf-8'), 'abc\n')
+
+ def test_readv(self):
+ self.build_tree([u'\N{INTERROBANG}'])
+ handler = smart.SmartServerRequestHandler(self.get_readonly_transport())
+ handler.dispatch_command('readv', (u'\N{INTERROBANG}',))
+ handler.accept_body('2,3')
+ handler.end_of_body()
+ self.assertEqual(('readv', ), handler.response.args)
+ # co - nte - nt of a-file is the file contents we are extracting from.
+ self.assertEqual('nte', handler.response.body)
+
+ def test_rename(self):
+ self.build_tree([u'one\N{INTERROBANG}'])
+ handler = smart.SmartServerRequestHandler(self.get_transport())
+ handler.dispatch_command(
+ 'rename', (u'one\N{INTERROBANG}', u'two\N{INTERROBANG}',))
+ self.assertEqual(('ok',), handler.response.args)
+ self.failIfExists(u'one\N{INTERROBANG}'.encode('utf-8'))
+ self.failUnlessExists(u'two\N{INTERROBANG}'.encode('utf-8'))
+
+ def test_rmdir(self):
+ self.build_tree([u'\N{INTERROBANG}/'])
+ handler = smart.SmartServerRequestHandler(self.get_transport())
+ handler.dispatch_command('rmdir', (u'\N{INTERROBANG}',))
+ self.assertEqual(('ok',), handler.response.args)
+ self.failIfExists(u'\N{INTERROBANG}'.encode('utf-8'))
+
+ def test_stat(self):
+ self.build_tree([u'\N{INTERROBANG}'])
+ handler = smart.SmartServerRequestHandler(self.get_readonly_transport())
+ handler.dispatch_command('stat', (u'\N{INTERROBANG}',))
+ self.assertEqual('stat', handler.response.args[0])
+
+
class SmartTransportRegistration(tests.TestCase):
def test_registration(self):
=== modified file bzrlib/transport/smart.py // last-changed:andrew.bennetts at can
... onical.com-20061012085801-36b60463388ea0e7
--- bzrlib/transport/smart.py
+++ bzrlib/transport/smart.py
@@ -560,6 +560,7 @@
return
bytes = self._in.read(bytes_to_read)
if bytes == '':
+
# Connection has been closed.
self.finished = True
self._out.flush()
@@ -635,10 +636,12 @@
return SmartServerResponse(('ok', '1'))
def do_has(self, relpath):
+ relpath = relpath.encode('utf-8')
r = self._backing_transport.has(relpath) and 'yes' or 'no'
return SmartServerResponse((r,))
def do_get(self, relpath):
+ relpath = relpath.encode('utf-8')
backing_bytes = self._backing_transport.get_bytes(relpath)
return SmartServerResponse(('ok',), backing_bytes)
@@ -651,7 +654,7 @@
def do_append(self, relpath, mode):
self._converted_command = True
- self._relpath = relpath
+ self._relpath = relpath.encode('utf-8')
self._mode = self._deserialise_optional_mode(mode)
self._end_of_body_handler = self._handle_do_append_end
@@ -661,29 +664,33 @@
self.response = SmartServerResponse(('appended', '%d' % old_length))
def do_delete(self, relpath):
+ relpath = relpath.encode('utf-8')
self._backing_transport.delete(relpath)
- def do_iter_files_recursive(self, abspath):
- # XXX: the path handling needs some thought.
- #relpath = self._backing_transport.relpath(abspath)
- transport = self._backing_transport.clone(abspath)
+ def do_iter_files_recursive(self, relpath):
+ relpath = relpath.encode('utf-8')
+ transport = self._backing_transport.clone(relpath)
filenames = transport.iter_files_recursive()
return SmartServerResponse(('names',) + tuple(filenames))
def do_list_dir(self, relpath):
+ relpath = relpath.encode('utf-8')
filenames = self._backing_transport.list_dir(relpath)
return SmartServerResponse(('names',) + tuple(filenames))
def do_mkdir(self, relpath, mode):
+ relpath = relpath.encode('utf-8')
self._backing_transport.mkdir(relpath,
self._deserialise_optional_mode(mode))
def do_move(self, rel_from, rel_to):
+ rel_from = rel_from.encode('utf-8')
+ rel_to = rel_to.encode('utf-8')
self._backing_transport.move(rel_from, rel_to)
def do_put(self, relpath, mode):
self._converted_command = True
- self._relpath = relpath
+ self._relpath = relpath.encode('utf-8')
self._mode = self._deserialise_optional_mode(mode)
self._end_of_body_handler = self._handle_do_put
@@ -705,7 +712,7 @@
def do_put_non_atomic(self, relpath, mode, create_parent, dir_mode):
self._converted_command = True
self._end_of_body_handler = self._handle_put_non_atomic
- self._relpath = relpath
+ self._relpath = relpath.encode('utf-8')
self._dir_mode = self._deserialise_optional_mode(dir_mode)
self._mode = self._deserialise_optional_mode(mode)
# a boolean would be nicer XXX
@@ -722,7 +729,7 @@
def do_readv(self, relpath):
self._converted_command = True
self._end_of_body_handler = self._handle_readv_offsets
- self._relpath = relpath
+ self._relpath = relpath.encode('utf-8')
def end_of_body(self):
"""No more body data will be received."""
@@ -738,12 +745,16 @@
self.response = SmartServerResponse(('readv',), backing_bytes)
def do_rename(self, rel_from, rel_to):
+ rel_from = rel_from.encode('utf-8')
+ rel_to = rel_to.encode('utf-8')
self._backing_transport.rename(rel_from, rel_to)
def do_rmdir(self, relpath):
+ relpath = relpath.encode('utf-8')
self._backing_transport.rmdir(relpath)
def do_stat(self, relpath):
+ relpath = relpath.encode('utf-8')
stat = self._backing_transport.stat(relpath)
return SmartServerResponse(('stat', str(stat.st_size), oct(stat.st_mode)))
# revision id: andrew.bennetts at canonical.com-20061012085943-220c54b5ae219365
# sha1: cc4875699d70f6688c7985c4038edf74e828a797
# inventory sha1: 91bed157d023d03ae4946d8e9baf125c448d71a7
# parent ids:
# andrew.bennetts at canonical.com-20061012085801-36b60463388ea0e7
# base id: andrew.bennetts at canonical.com-20061012063051-5efaeb5409f0dbad
# properties:
# branch-nick: smart server unicode
# message:
# Fix dispatching of smart server requests involving unicode paths.
# committer: Andrew Bennetts <andrew.bennetts at canonical.com>
# date: Thu 2006-10-12 18:58:01.677000046 +1000
=== modified file bzrlib/tests/test_smart_transport.py // encoding:base64
LS0tIGJ6cmxpYi90ZXN0cy90ZXN0X3NtYXJ0X3RyYW5zcG9ydC5weQorKysgYnpybGliL3Rlc3Rz
L3Rlc3Rfc21hcnRfdHJhbnNwb3J0LnB5CkBAIC01OTYsNyArNTk2LDcgQEAKICAgICAgICAgc2Vs
Zi5hc3NlcnRFcXVhbCgnb2tcMDAxMVxuJywKICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9t
X3NlcnZlci5nZXR2YWx1ZSgpKQogCi0gICAgZGVmIHRlc3RfY2FubmVkX2dldF9yZXNwb25zZShz
ZWxmKToKKyAgICBkZWYgdGVzdF9yZXNwb25zZV90b19jYW5uZWRfZ2V0KHNlbGYpOgogICAgICAg
ICB0cmFuc3BvcnQgPSBtZW1vcnkuTWVtb3J5VHJhbnNwb3J0KCdtZW1vcnk6Ly8vJykKICAgICAg
ICAgdHJhbnNwb3J0LnB1dF9ieXRlcygndGVzdGZpbGUnLCAnY29udGVudHNcbm9mXG5maWxlXG4n
KQogICAgICAgICB0b19zZXJ2ZXIgPSBTdHJpbmdJTygnZ2V0XDAwMS4vdGVzdGZpbGVcbicpCkBA
IC02MTIsNiArNjEyLDI0IEBACiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2RvbmVcbicsCiAg
ICAgICAgICAgICAgICAgICAgICAgICAgZnJvbV9zZXJ2ZXIuZ2V0dmFsdWUoKSkKIAorICAgIGRl
ZiB0ZXN0X3Jlc3BvbnNlX3RvX2Nhbm5lZF9nZXRfb2ZfdXRmOChzZWxmKToKKyAgICAgICAgIyB3
aXJlLXRvLXdpcmUsIHVzaW5nIHRoZSB3aG9sZSBzdGFjaywgd2l0aCBhIFVURi04IGZpbGVuYW1l
LgorICAgICAgICB0cmFuc3BvcnQgPSBtZW1vcnkuTWVtb3J5VHJhbnNwb3J0KCdtZW1vcnk6Ly8v
JykKKyAgICAgICAgdXRmOF9maWxlbmFtZSA9IHUndGVzdGZpbGVcTntJTlRFUlJPQkFOR30nLmVu
Y29kZSgndXRmLTgnKQorICAgICAgICB0cmFuc3BvcnQucHV0X2J5dGVzKHV0ZjhfZmlsZW5hbWUs
ICdjb250ZW50c1xub2ZcbmZpbGVcbicpCisgICAgICAgIHRvX3NlcnZlciA9IFN0cmluZ0lPKCdn
ZXRcMDAxJyArIHV0ZjhfZmlsZW5hbWUgKyAnXG4nKQorICAgICAgICBmcm9tX3NlcnZlciA9IFN0
cmluZ0lPKCkKKyAgICAgICAgc2VydmVyID0gc21hcnQuU21hcnRTZXJ2ZXJQaXBlU3RyZWFtTWVk
aXVtKAorICAgICAgICAgICAgdG9fc2VydmVyLCBmcm9tX3NlcnZlciwgdHJhbnNwb3J0KQorICAg
ICAgICBwcm90b2NvbCA9IHNtYXJ0LlNtYXJ0U2VydmVyUmVxdWVzdFByb3RvY29sT25lKHRyYW5z
cG9ydCwKKyAgICAgICAgICAgICAgICBmcm9tX3NlcnZlci53cml0ZSkKKyAgICAgICAgc2VydmVy
Ll9zZXJ2ZV9vbmVfcmVxdWVzdChwcm90b2NvbCkKKyAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgn
b2tcbicKKyAgICAgICAgICAgICAgICAgICAgICAgICAnMTdcbicKKyAgICAgICAgICAgICAgICAg
ICAgICAgICAnY29udGVudHNcbm9mXG5maWxlXG4nCisgICAgICAgICAgICAgICAgICAgICAgICAg
J2RvbmVcbicsCisgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbV9zZXJ2ZXIuZ2V0dmFsdWUo
KSkKKwogICAgIGRlZiB0ZXN0X3BpcGVfbGlrZV9zdHJlYW1fd2l0aF9idWxrX2RhdGEoc2VsZik6
CiAgICAgICAgIHNhbXBsZV9yZXF1ZXN0X2J5dGVzID0gJ2NvbW1hbmRcbjlcbmJ1bGsgZGF0YWRv
bmVcbicKICAgICAgICAgdG9fc2VydmVyID0gU3RyaW5nSU8oc2FtcGxlX3JlcXVlc3RfYnl0ZXMp
CkBAIC05MzMsNyArOTUxLDcgQEAKICAgICBkZWYgdGVzdF9wdXRfYnl0ZXNfbm9uX2F0b21pYyhz
ZWxmKToKICAgICAgICAgIiIiJ3B1dF8uLi4nIHNob3VsZCBzZXQgZmluaXNoZWRfcmVhZGluZyBh
ZnRlciByZWFkaW5nIHRoZSBieXRlcy4iIiIKICAgICAgICAgaGFuZGxlciA9IHNtYXJ0LlNtYXJ0
U2VydmVyUmVxdWVzdEhhbmRsZXIoc2VsZi5nZXRfdHJhbnNwb3J0KCkpCi0gICAgICAgIGhhbmRs
ZXIuZGlzcGF0Y2hfY29tbWFuZCgncHV0X25vbl9hdG9taWMnLCAoJ2EtZmlsZScsICcnLCAnRics
ICcnKSkKKyAgICAgICAgaGFuZGxlci5kaXNwYXRjaF9jb21tYW5kKCdwdXRfbm9uX2F0b21pYycs
ICh1J2EtZmlsZScsIHUnJywgdSdGJywgdScnKSkKICAgICAgICAgc2VsZi5hc3NlcnRGYWxzZSho
YW5kbGVyLmZpbmlzaGVkX3JlYWRpbmcpCiAgICAgICAgIGhhbmRsZXIuYWNjZXB0X2JvZHkoJzEy
MzQnKQogICAgICAgICBzZWxmLmFzc2VydEZhbHNlKGhhbmRsZXIuZmluaXNoZWRfcmVhZGluZykK
QEAgLTk0Nyw3ICs5NjUsNyBAQAogICAgICAgICAiIiIncmVhZHYnIHNob3VsZCBzZXQgZmluaXNo
ZWRfcmVhZGluZyBhZnRlciByZWFkaW5nIG9mZnNldHMuIiIiCiAgICAgICAgIHNlbGYuYnVpbGRf
dHJlZShbJ2EtZmlsZSddKQogICAgICAgICBoYW5kbGVyID0gc21hcnQuU21hcnRTZXJ2ZXJSZXF1
ZXN0SGFuZGxlcihzZWxmLmdldF9yZWFkb25seV90cmFuc3BvcnQoKSkKLSAgICAgICAgaGFuZGxl
ci5kaXNwYXRjaF9jb21tYW5kKCdyZWFkdicsICgnYS1maWxlJywgKSkKKyAgICAgICAgaGFuZGxl
ci5kaXNwYXRjaF9jb21tYW5kKCdyZWFkdicsICh1J2EtZmlsZScsICkpCiAgICAgICAgIHNlbGYu
YXNzZXJ0RmFsc2UoaGFuZGxlci5maW5pc2hlZF9yZWFkaW5nKQogICAgICAgICBoYW5kbGVyLmFj
Y2VwdF9ib2R5KCcyLCcpCiAgICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UoaGFuZGxlci5maW5pc2hl
ZF9yZWFkaW5nKQpAQCAtOTYyLDcgKzk4MCw3IEBACiAgICAgICAgICIiIidyZWFkdicgd2hlbiBh
IHNob3J0IHJlYWQgb2NjdXJzIHNldHMgdGhlIHJlc3BvbnNlIGFwcHJvcHJpYXRlbHkuIiIiCiAg
ICAgICAgIHNlbGYuYnVpbGRfdHJlZShbJ2EtZmlsZSddKQogICAgICAgICBoYW5kbGVyID0gc21h
cnQuU21hcnRTZXJ2ZXJSZXF1ZXN0SGFuZGxlcihzZWxmLmdldF9yZWFkb25seV90cmFuc3BvcnQo
KSkKLSAgICAgICAgaGFuZGxlci5kaXNwYXRjaF9jb21tYW5kKCdyZWFkdicsICgnYS1maWxlJywg
KSkKKyAgICAgICAgaGFuZGxlci5kaXNwYXRjaF9jb21tYW5kKCdyZWFkdicsICh1J2EtZmlsZScs
ICkpCiAgICAgICAgICMgcmVhZCBiZXlvbmQgdGhlIGVuZCBvZiB0aGUgZmlsZS4KICAgICAgICAg
aGFuZGxlci5hY2NlcHRfYm9keSgnMTAwLDEnKQogICAgICAgICBoYW5kbGVyLmVuZF9vZl9ib2R5
KCkKQEAgLTk3Miw2ICs5OTAsMTMyIEBACiAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoTm9uZSwg
aGFuZGxlci5yZXNwb25zZS5ib2R5KQogCiAKK2NsYXNzIFNtYXJ0U2VydmVyUmVxdWVzdEhhbmRs
ZXJVbmljb2RlVGVzdHModGVzdHMuVGVzdENhc2VXaXRoVHJhbnNwb3J0KToKKyAgICAiIiJUZXN0
IHVuaWNvZGUgcmVscGF0aHMgcGFzc2VkIHRvIHRoZSByZXF1ZXN0IGhhbmRsZXIuCisKKyAgICBT
bWFydFNlcnZlclJlcXVlc3RQcm90b2NvbE9uZSBkZWNvZGVzIHJlcXVlc3RzIGludG8gYSB0dXBs
ZSBvZiB1bmljb2RlCisgICAgb2JqZWN0cy4gIFRoYXQgdHVwbGUgaXMgdGhlbiBwYXNzZWQgdG8g
dGhlIHJlcXVlc3QgaGFuZGxlcidzCisgICAgZGlzcGF0Y2hfY29tbWFuZCBtZXRob2QuICBUaGlz
IHRlc3QgY2FzZSBpcyBmb3IgdGVzdGluZyB0aGF0IHVuaWNvZGUgcGF0aHMKKyAgICBhcmUgaGFu
ZGxlZCBjb3JyZWN0bHkgYnkgdGhlIHJlcXVlc3QgaGFuZGxlci4KKyAgICAiIiIKKworICAgIGRl
ZiB0ZXN0X2dldF9maWxlKHNlbGYpOgorICAgICAgICBzZWxmLmJ1aWxkX3RyZWUoW3UnXE57SU5U
RVJST0JBTkd9J10sIGxpbmVfZW5kaW5ncz0nYmluYXJ5JykKKyAgICAgICAgaGFuZGxlciA9IHNt
YXJ0LlNtYXJ0U2VydmVyUmVxdWVzdEhhbmRsZXIoc2VsZi5nZXRfcmVhZG9ubHlfdHJhbnNwb3J0
KCkpCisgICAgICAgIGhhbmRsZXIuZGlzcGF0Y2hfY29tbWFuZCgnZ2V0JywgKHUnXE57SU5URVJS
T0JBTkd9JywpKQorICAgICAgICBzZWxmLmFzc2VydEVxdWFsKCgnb2snLCksIGhhbmRsZXIucmVz
cG9uc2UuYXJncykKKyAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgKKyAgICAgICAgICAgIHUnY29u
dGVudHMgb2YgXE57SU5URVJST0JBTkd9XG4nLmVuY29kZSgndXRmLTgnKSwKKyAgICAgICAgICAg
IGhhbmRsZXIucmVzcG9uc2UuYm9keSkKKworICAgIGRlZiB0ZXN0X2hhcyhzZWxmKToKKyAgICAg
ICAgc2VsZi5idWlsZF90cmVlKFt1J1xOe0lOVEVSUk9CQU5HfSddKQorICAgICAgICBoYW5kbGVy
ID0gc21hcnQuU21hcnRTZXJ2ZXJSZXF1ZXN0SGFuZGxlcihzZWxmLmdldF9yZWFkb25seV90cmFu
c3BvcnQoKSkKKyAgICAgICAgaGFuZGxlci5kaXNwYXRjaF9jb21tYW5kKCdoYXMnLCAodSdcTntJ
TlRFUlJPQkFOR30nLCkpCisgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoKCd5ZXMnLCksIGhhbmRs
ZXIucmVzcG9uc2UuYXJncykKKworICAgIGRlZiB0ZXN0X2FwcGVuZChzZWxmKToKKyAgICAgICAg
aGFuZGxlciA9IHNtYXJ0LlNtYXJ0U2VydmVyUmVxdWVzdEhhbmRsZXIoc2VsZi5nZXRfdHJhbnNw
b3J0KCkpCisgICAgICAgIGhhbmRsZXIuZGlzcGF0Y2hfY29tbWFuZCgnYXBwZW5kJywgKHUnXE57
SU5URVJST0JBTkd9JywgJycpKQorICAgICAgICBoYW5kbGVyLmFjY2VwdF9ib2R5KCdhYmNcbicp
CisgICAgICAgIGhhbmRsZXIuZW5kX29mX2JvZHkoKQorICAgICAgICBzZWxmLmFzc2VydEVxdWFs
KCgnYXBwZW5kZWQnLCAnMCcpLCBoYW5kbGVyLnJlc3BvbnNlLmFyZ3MpCisgICAgICAgIHNlbGYu
Y2hlY2tfZmlsZV9jb250ZW50cyh1J1xOe0lOVEVSUk9CQU5HfScuZW5jb2RlKCd1dGYtOCcpLCAn
YWJjXG4nKQorCisgICAgZGVmIHRlc3RfZGVsZXRlKHNlbGYpOgorICAgICAgICBzZWxmLmJ1aWxk
X3RyZWUoW3UnXE57SU5URVJST0JBTkd9J10pCisgICAgICAgIGhhbmRsZXIgPSBzbWFydC5TbWFy
dFNlcnZlclJlcXVlc3RIYW5kbGVyKHNlbGYuZ2V0X3RyYW5zcG9ydCgpKQorICAgICAgICBoYW5k
bGVyLmRpc3BhdGNoX2NvbW1hbmQoJ2RlbGV0ZScsICh1J1xOe0lOVEVSUk9CQU5HfScsKSkKKyAg
ICAgICAgc2VsZi5hc3NlcnRFcXVhbCgoJ29rJywpLCBoYW5kbGVyLnJlc3BvbnNlLmFyZ3MpCisg
ICAgICAgIHNlbGYuZmFpbElmRXhpc3RzKHUnXE57SU5URVJST0JBTkd9Jy5lbmNvZGUoJ3V0Zi04
JykpCisKKyAgICBkZWYgdGVzdF9pdGVyX2ZpbGVzX3JlY3Vyc2l2ZShzZWxmKToKKyAgICAgICAg
c2VsZi5idWlsZF90cmVlKFsKKyAgICAgICAgICAgIHUnXE57SU5URVJST0JBTkd9LycsCisgICAg
ICAgICAgICB1J1xOe0lOVEVSUk9CQU5HfS9vbmUnLAorICAgICAgICAgICAgdSdcTntJTlRFUlJP
QkFOR30vdHdvJywKKyAgICAgICAgICAgIF0pCisgICAgICAgIGhhbmRsZXIgPSBzbWFydC5TbWFy
dFNlcnZlclJlcXVlc3RIYW5kbGVyKHNlbGYuZ2V0X3JlYWRvbmx5X3RyYW5zcG9ydCgpKQorICAg
ICAgICBoYW5kbGVyLmRpc3BhdGNoX2NvbW1hbmQoJ2l0ZXJfZmlsZXNfcmVjdXJzaXZlJywgKHUn
XE57SU5URVJST0JBTkd9JywpKQorICAgICAgICBzZWxmLmFzc2VydEVxdWFsKCduYW1lcycsIGhh
bmRsZXIucmVzcG9uc2UuYXJnc1swXSkKKyAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChzZXQoWydv
bmUnLCAndHdvJ10pLCBzZXQoaGFuZGxlci5yZXNwb25zZS5hcmdzWzE6XSkpCisKKyAgICBkZWYg
dGVzdF9saXN0X2RpcihzZWxmKToKKyAgICAgICAgc2VsZi5idWlsZF90cmVlKFsKKyAgICAgICAg
ICAgIHUnXE57SU5URVJST0JBTkd9LycsCisgICAgICAgICAgICB1J1xOe0lOVEVSUk9CQU5HfS9v
bmUnLAorICAgICAgICAgICAgdSdcTntJTlRFUlJPQkFOR30vdHdvJywKKyAgICAgICAgICAgIF0p
CisgICAgICAgIGhhbmRsZXIgPSBzbWFydC5TbWFydFNlcnZlclJlcXVlc3RIYW5kbGVyKHNlbGYu
Z2V0X3JlYWRvbmx5X3RyYW5zcG9ydCgpKQorICAgICAgICBoYW5kbGVyLmRpc3BhdGNoX2NvbW1h
bmQoJ2xpc3RfZGlyJywgKHUnXE57SU5URVJST0JBTkd9JywpKQorICAgICAgICBzZWxmLmFzc2Vy
dEVxdWFsKCduYW1lcycsIGhhbmRsZXIucmVzcG9uc2UuYXJnc1swXSkKKyAgICAgICAgc2VsZi5h
c3NlcnRFcXVhbChzZXQoWydvbmUnLCAndHdvJ10pLCBzZXQoaGFuZGxlci5yZXNwb25zZS5hcmdz
WzE6XSkpCisKKyAgICBkZWYgdGVzdF9ta2RpcihzZWxmKToKKyAgICAgICAgaGFuZGxlciA9IHNt
YXJ0LlNtYXJ0U2VydmVyUmVxdWVzdEhhbmRsZXIoc2VsZi5nZXRfdHJhbnNwb3J0KCkpCisgICAg
ICAgIGhhbmRsZXIuZGlzcGF0Y2hfY29tbWFuZCgnbWtkaXInLCAodSdcTntJTlRFUlJPQkFOR30n
LCAnJykpCisgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoKCdvaycsKSwgaGFuZGxlci5yZXNwb25z
ZS5hcmdzKQorICAgICAgICBzZWxmLmZhaWxVbmxlc3NFeGlzdHModSdcTntJTlRFUlJPQkFOR30n
LmVuY29kZSgndXRmLTgnKSkKKworICAgIGRlZiB0ZXN0X21vdmUoc2VsZik6CisgICAgICAgIHNl
bGYuYnVpbGRfdHJlZShbdSdvbmVcTntJTlRFUlJPQkFOR30nXSkKKyAgICAgICAgaGFuZGxlciA9
IHNtYXJ0LlNtYXJ0U2VydmVyUmVxdWVzdEhhbmRsZXIoc2VsZi5nZXRfdHJhbnNwb3J0KCkpCisg
ICAgICAgIGhhbmRsZXIuZGlzcGF0Y2hfY29tbWFuZCgKKyAgICAgICAgICAgICdtb3ZlJywgKHUn
b25lXE57SU5URVJST0JBTkd9JywgdSd0d29cTntJTlRFUlJPQkFOR30nLCkpCisgICAgICAgIHNl
bGYuYXNzZXJ0RXF1YWwoKCdvaycsKSwgaGFuZGxlci5yZXNwb25zZS5hcmdzKQorICAgICAgICBz
ZWxmLmZhaWxJZkV4aXN0cyh1J29uZVxOe0lOVEVSUk9CQU5HfScuZW5jb2RlKCd1dGYtOCcpKQor
ICAgICAgICBzZWxmLmZhaWxVbmxlc3NFeGlzdHModSd0d29cTntJTlRFUlJPQkFOR30nLmVuY29k
ZSgndXRmLTgnKSkKKworICAgIGRlZiB0ZXN0X3B1dChzZWxmKToKKyAgICAgICAgaGFuZGxlciA9
IHNtYXJ0LlNtYXJ0U2VydmVyUmVxdWVzdEhhbmRsZXIoc2VsZi5nZXRfdHJhbnNwb3J0KCkpCisg
ICAgICAgIGhhbmRsZXIuZGlzcGF0Y2hfY29tbWFuZCgncHV0JywgKHUnXE57SU5URVJST0JBTkd9
JywgJycpKQorICAgICAgICBoYW5kbGVyLmFjY2VwdF9ib2R5KCdhYmNcbicpCisgICAgICAgIGhh
bmRsZXIuZW5kX29mX2JvZHkoKQorICAgICAgICBzZWxmLmFzc2VydEVxdWFsKCgnb2snLCksIGhh
bmRsZXIucmVzcG9uc2UuYXJncykKKyAgICAgICAgc2VsZi5jaGVja19maWxlX2NvbnRlbnRzKHUn
XE57SU5URVJST0JBTkd9Jy5lbmNvZGUoJ3V0Zi04JyksICdhYmNcbicpCisKKyAgICBkZWYgdGVz
dF9wdXRfbm9uX2F0b21pYyhzZWxmKToKKyAgICAgICAgaGFuZGxlciA9IHNtYXJ0LlNtYXJ0U2Vy
dmVyUmVxdWVzdEhhbmRsZXIoc2VsZi5nZXRfdHJhbnNwb3J0KCkpCisgICAgICAgIGhhbmRsZXIu
ZGlzcGF0Y2hfY29tbWFuZCgKKyAgICAgICAgICAgICdwdXRfbm9uX2F0b21pYycsICh1J1xOe0lO
VEVSUk9CQU5HfScsICcnLCAnRicsICcnKSkKKyAgICAgICAgaGFuZGxlci5hY2NlcHRfYm9keSgn
YWJjXG4nKQorICAgICAgICBoYW5kbGVyLmVuZF9vZl9ib2R5KCkKKyAgICAgICAgc2VsZi5hc3Nl
cnRFcXVhbCgoJ29rJywpLCBoYW5kbGVyLnJlc3BvbnNlLmFyZ3MpCisgICAgICAgIHNlbGYuY2hl
Y2tfZmlsZV9jb250ZW50cyh1J1xOe0lOVEVSUk9CQU5HfScuZW5jb2RlKCd1dGYtOCcpLCAnYWJj
XG4nKQorCisgICAgZGVmIHRlc3RfcmVhZHYoc2VsZik6CisgICAgICAgIHNlbGYuYnVpbGRfdHJl
ZShbdSdcTntJTlRFUlJPQkFOR30nXSkKKyAgICAgICAgaGFuZGxlciA9IHNtYXJ0LlNtYXJ0U2Vy
dmVyUmVxdWVzdEhhbmRsZXIoc2VsZi5nZXRfcmVhZG9ubHlfdHJhbnNwb3J0KCkpCisgICAgICAg
IGhhbmRsZXIuZGlzcGF0Y2hfY29tbWFuZCgncmVhZHYnLCAodSdcTntJTlRFUlJPQkFOR30nLCkp
CisgICAgICAgIGhhbmRsZXIuYWNjZXB0X2JvZHkoJzIsMycpCisgICAgICAgIGhhbmRsZXIuZW5k
X29mX2JvZHkoKQorICAgICAgICBzZWxmLmFzc2VydEVxdWFsKCgncmVhZHYnLCApLCBoYW5kbGVy
LnJlc3BvbnNlLmFyZ3MpCisgICAgICAgICMgY28gLSBudGUgLSBudCBvZiBhLWZpbGUgaXMgdGhl
IGZpbGUgY29udGVudHMgd2UgYXJlIGV4dHJhY3RpbmcgZnJvbS4KKyAgICAgICAgc2VsZi5hc3Nl
cnRFcXVhbCgnbnRlJywgaGFuZGxlci5yZXNwb25zZS5ib2R5KQorCisgICAgZGVmIHRlc3RfcmVu
YW1lKHNlbGYpOgorICAgICAgICBzZWxmLmJ1aWxkX3RyZWUoW3Unb25lXE57SU5URVJST0JBTkd9
J10pCisgICAgICAgIGhhbmRsZXIgPSBzbWFydC5TbWFydFNlcnZlclJlcXVlc3RIYW5kbGVyKHNl
bGYuZ2V0X3RyYW5zcG9ydCgpKQorICAgICAgICBoYW5kbGVyLmRpc3BhdGNoX2NvbW1hbmQoCisg
ICAgICAgICAgICAncmVuYW1lJywgKHUnb25lXE57SU5URVJST0JBTkd9JywgdSd0d29cTntJTlRF
UlJPQkFOR30nLCkpCisgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoKCdvaycsKSwgaGFuZGxlci5y
ZXNwb25zZS5hcmdzKQorICAgICAgICBzZWxmLmZhaWxJZkV4aXN0cyh1J29uZVxOe0lOVEVSUk9C
QU5HfScuZW5jb2RlKCd1dGYtOCcpKQorICAgICAgICBzZWxmLmZhaWxVbmxlc3NFeGlzdHModSd0
d29cTntJTlRFUlJPQkFOR30nLmVuY29kZSgndXRmLTgnKSkKKworICAgIGRlZiB0ZXN0X3JtZGly
KHNlbGYpOgorICAgICAgICBzZWxmLmJ1aWxkX3RyZWUoW3UnXE57SU5URVJST0JBTkd9LyddKQor
ICAgICAgICBoYW5kbGVyID0gc21hcnQuU21hcnRTZXJ2ZXJSZXF1ZXN0SGFuZGxlcihzZWxmLmdl
dF90cmFuc3BvcnQoKSkKKyAgICAgICAgaGFuZGxlci5kaXNwYXRjaF9jb21tYW5kKCdybWRpcics
ICh1J1xOe0lOVEVSUk9CQU5HfScsKSkKKyAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgoJ29rJywp
LCBoYW5kbGVyLnJlc3BvbnNlLmFyZ3MpCisgICAgICAgIHNlbGYuZmFpbElmRXhpc3RzKHUnXE57
SU5URVJST0JBTkd9Jy5lbmNvZGUoJ3V0Zi04JykpCisKKyAgICBkZWYgdGVzdF9zdGF0KHNlbGYp
OgorICAgICAgICBzZWxmLmJ1aWxkX3RyZWUoW3UnXE57SU5URVJST0JBTkd9J10pCisgICAgICAg
IGhhbmRsZXIgPSBzbWFydC5TbWFydFNlcnZlclJlcXVlc3RIYW5kbGVyKHNlbGYuZ2V0X3JlYWRv
bmx5X3RyYW5zcG9ydCgpKQorICAgICAgICBoYW5kbGVyLmRpc3BhdGNoX2NvbW1hbmQoJ3N0YXQn
LCAodSdcTntJTlRFUlJPQkFOR30nLCkpCisgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ3N0YXQn
LCBoYW5kbGVyLnJlc3BvbnNlLmFyZ3NbMF0pCisKKwogY2xhc3MgU21hcnRUcmFuc3BvcnRSZWdp
c3RyYXRpb24odGVzdHMuVGVzdENhc2UpOgogCiAgICAgZGVmIHRlc3RfcmVnaXN0cmF0aW9uKHNl
bGYpOgoK
=== modified file bzrlib/transport/smart.py // encoding:base64
LS0tIGJ6cmxpYi90cmFuc3BvcnQvc21hcnQucHkKKysrIGJ6cmxpYi90cmFuc3BvcnQvc21hcnQu
cHkKQEAgLTU2MCw2ICs1NjAsNyBAQAogICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAg
ICAgYnl0ZXMgPSBzZWxmLl9pbi5yZWFkKGJ5dGVzX3RvX3JlYWQpCiAgICAgICAgICAgICBpZiBi
eXRlcyA9PSAnJzoKKwogICAgICAgICAgICAgICAgICMgQ29ubmVjdGlvbiBoYXMgYmVlbiBjbG9z
ZWQuCiAgICAgICAgICAgICAgICAgc2VsZi5maW5pc2hlZCA9IFRydWUKICAgICAgICAgICAgICAg
ICBzZWxmLl9vdXQuZmx1c2goKQpAQCAtNjM1LDEwICs2MzYsMTIgQEAKICAgICAgICAgcmV0dXJu
IFNtYXJ0U2VydmVyUmVzcG9uc2UoKCdvaycsICcxJykpCiAKICAgICBkZWYgZG9faGFzKHNlbGYs
IHJlbHBhdGgpOgorICAgICAgICByZWxwYXRoID0gcmVscGF0aC5lbmNvZGUoJ3V0Zi04JykKICAg
ICAgICAgciA9IHNlbGYuX2JhY2tpbmdfdHJhbnNwb3J0LmhhcyhyZWxwYXRoKSBhbmQgJ3llcycg
b3IgJ25vJwogICAgICAgICByZXR1cm4gU21hcnRTZXJ2ZXJSZXNwb25zZSgociwpKQogCiAgICAg
ZGVmIGRvX2dldChzZWxmLCByZWxwYXRoKToKKyAgICAgICAgcmVscGF0aCA9IHJlbHBhdGguZW5j
b2RlKCd1dGYtOCcpCiAgICAgICAgIGJhY2tpbmdfYnl0ZXMgPSBzZWxmLl9iYWNraW5nX3RyYW5z
cG9ydC5nZXRfYnl0ZXMocmVscGF0aCkKICAgICAgICAgcmV0dXJuIFNtYXJ0U2VydmVyUmVzcG9u
c2UoKCdvaycsKSwgYmFja2luZ19ieXRlcykKIApAQCAtNjUxLDcgKzY1NCw3IEBACiAKICAgICBk
ZWYgZG9fYXBwZW5kKHNlbGYsIHJlbHBhdGgsIG1vZGUpOgogICAgICAgICBzZWxmLl9jb252ZXJ0
ZWRfY29tbWFuZCA9IFRydWUKLSAgICAgICAgc2VsZi5fcmVscGF0aCA9IHJlbHBhdGgKKyAgICAg
ICAgc2VsZi5fcmVscGF0aCA9IHJlbHBhdGguZW5jb2RlKCd1dGYtOCcpCiAgICAgICAgIHNlbGYu
X21vZGUgPSBzZWxmLl9kZXNlcmlhbGlzZV9vcHRpb25hbF9tb2RlKG1vZGUpCiAgICAgICAgIHNl
bGYuX2VuZF9vZl9ib2R5X2hhbmRsZXIgPSBzZWxmLl9oYW5kbGVfZG9fYXBwZW5kX2VuZAogICAg
IApAQCAtNjYxLDI5ICs2NjQsMzMgQEAKICAgICAgICAgc2VsZi5yZXNwb25zZSA9IFNtYXJ0U2Vy
dmVyUmVzcG9uc2UoKCdhcHBlbmRlZCcsICclZCcgJSBvbGRfbGVuZ3RoKSkKIAogICAgIGRlZiBk
b19kZWxldGUoc2VsZiwgcmVscGF0aCk6CisgICAgICAgIHJlbHBhdGggPSByZWxwYXRoLmVuY29k
ZSgndXRmLTgnKQogICAgICAgICBzZWxmLl9iYWNraW5nX3RyYW5zcG9ydC5kZWxldGUocmVscGF0
aCkKIAotICAgIGRlZiBkb19pdGVyX2ZpbGVzX3JlY3Vyc2l2ZShzZWxmLCBhYnNwYXRoKToKLSAg
ICAgICAgIyBYWFg6IHRoZSBwYXRoIGhhbmRsaW5nIG5lZWRzIHNvbWUgdGhvdWdodC4KLSAgICAg
ICAgI3JlbHBhdGggPSBzZWxmLl9iYWNraW5nX3RyYW5zcG9ydC5yZWxwYXRoKGFic3BhdGgpCi0g
ICAgICAgIHRyYW5zcG9ydCA9IHNlbGYuX2JhY2tpbmdfdHJhbnNwb3J0LmNsb25lKGFic3BhdGgp
CisgICAgZGVmIGRvX2l0ZXJfZmlsZXNfcmVjdXJzaXZlKHNlbGYsIHJlbHBhdGgpOgorICAgICAg
ICByZWxwYXRoID0gcmVscGF0aC5lbmNvZGUoJ3V0Zi04JykKKyAgICAgICAgdHJhbnNwb3J0ID0g
c2VsZi5fYmFja2luZ190cmFuc3BvcnQuY2xvbmUocmVscGF0aCkKICAgICAgICAgZmlsZW5hbWVz
ID0gdHJhbnNwb3J0Lml0ZXJfZmlsZXNfcmVjdXJzaXZlKCkKICAgICAgICAgcmV0dXJuIFNtYXJ0
U2VydmVyUmVzcG9uc2UoKCduYW1lcycsKSArIHR1cGxlKGZpbGVuYW1lcykpCiAKICAgICBkZWYg
ZG9fbGlzdF9kaXIoc2VsZiwgcmVscGF0aCk6CisgICAgICAgIHJlbHBhdGggPSByZWxwYXRoLmVu
Y29kZSgndXRmLTgnKQogICAgICAgICBmaWxlbmFtZXMgPSBzZWxmLl9iYWNraW5nX3RyYW5zcG9y
dC5saXN0X2RpcihyZWxwYXRoKQogICAgICAgICByZXR1cm4gU21hcnRTZXJ2ZXJSZXNwb25zZSgo
J25hbWVzJywpICsgdHVwbGUoZmlsZW5hbWVzKSkKIAogICAgIGRlZiBkb19ta2RpcihzZWxmLCBy
ZWxwYXRoLCBtb2RlKToKKyAgICAgICAgcmVscGF0aCA9IHJlbHBhdGguZW5jb2RlKCd1dGYtOCcp
CiAgICAgICAgIHNlbGYuX2JhY2tpbmdfdHJhbnNwb3J0Lm1rZGlyKHJlbHBhdGgsCiAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2Rlc2VyaWFsaXNlX29wdGlvbmFs
X21vZGUobW9kZSkpCiAKICAgICBkZWYgZG9fbW92ZShzZWxmLCByZWxfZnJvbSwgcmVsX3RvKToK
KyAgICAgICAgcmVsX2Zyb20gPSByZWxfZnJvbS5lbmNvZGUoJ3V0Zi04JykKKyAgICAgICAgcmVs
X3RvID0gcmVsX3RvLmVuY29kZSgndXRmLTgnKQogICAgICAgICBzZWxmLl9iYWNraW5nX3RyYW5z
cG9ydC5tb3ZlKHJlbF9mcm9tLCByZWxfdG8pCiAKICAgICBkZWYgZG9fcHV0KHNlbGYsIHJlbHBh
dGgsIG1vZGUpOgogICAgICAgICBzZWxmLl9jb252ZXJ0ZWRfY29tbWFuZCA9IFRydWUKLSAgICAg
ICAgc2VsZi5fcmVscGF0aCA9IHJlbHBhdGgKKyAgICAgICAgc2VsZi5fcmVscGF0aCA9IHJlbHBh
dGguZW5jb2RlKCd1dGYtOCcpCiAgICAgICAgIHNlbGYuX21vZGUgPSBzZWxmLl9kZXNlcmlhbGlz
ZV9vcHRpb25hbF9tb2RlKG1vZGUpCiAgICAgICAgIHNlbGYuX2VuZF9vZl9ib2R5X2hhbmRsZXIg
PSBzZWxmLl9oYW5kbGVfZG9fcHV0CiAKQEAgLTcwNSw3ICs3MTIsNyBAQAogICAgIGRlZiBkb19w
dXRfbm9uX2F0b21pYyhzZWxmLCByZWxwYXRoLCBtb2RlLCBjcmVhdGVfcGFyZW50LCBkaXJfbW9k
ZSk6CiAgICAgICAgIHNlbGYuX2NvbnZlcnRlZF9jb21tYW5kID0gVHJ1ZQogICAgICAgICBzZWxm
Ll9lbmRfb2ZfYm9keV9oYW5kbGVyID0gc2VsZi5faGFuZGxlX3B1dF9ub25fYXRvbWljCi0gICAg
ICAgIHNlbGYuX3JlbHBhdGggPSByZWxwYXRoCisgICAgICAgIHNlbGYuX3JlbHBhdGggPSByZWxw
YXRoLmVuY29kZSgndXRmLTgnKQogICAgICAgICBzZWxmLl9kaXJfbW9kZSA9IHNlbGYuX2Rlc2Vy
aWFsaXNlX29wdGlvbmFsX21vZGUoZGlyX21vZGUpCiAgICAgICAgIHNlbGYuX21vZGUgPSBzZWxm
Ll9kZXNlcmlhbGlzZV9vcHRpb25hbF9tb2RlKG1vZGUpCiAgICAgICAgICMgYSBib29sZWFuIHdv
dWxkIGJlIG5pY2VyIFhYWApAQCAtNzIyLDcgKzcyOSw3IEBACiAgICAgZGVmIGRvX3JlYWR2KHNl
bGYsIHJlbHBhdGgpOgogICAgICAgICBzZWxmLl9jb252ZXJ0ZWRfY29tbWFuZCA9IFRydWUKICAg
ICAgICAgc2VsZi5fZW5kX29mX2JvZHlfaGFuZGxlciA9IHNlbGYuX2hhbmRsZV9yZWFkdl9vZmZz
ZXRzCi0gICAgICAgIHNlbGYuX3JlbHBhdGggPSByZWxwYXRoCisgICAgICAgIHNlbGYuX3JlbHBh
dGggPSByZWxwYXRoLmVuY29kZSgndXRmLTgnKQogCiAgICAgZGVmIGVuZF9vZl9ib2R5KHNlbGYp
OgogICAgICAgICAiIiJObyBtb3JlIGJvZHkgZGF0YSB3aWxsIGJlIHJlY2VpdmVkLiIiIgpAQCAt
NzM4LDEyICs3NDUsMTYgQEAKICAgICAgICAgc2VsZi5yZXNwb25zZSA9IFNtYXJ0U2VydmVyUmVz
cG9uc2UoKCdyZWFkdicsKSwgYmFja2luZ19ieXRlcykKICAgICAgICAgCiAgICAgZGVmIGRvX3Jl
bmFtZShzZWxmLCByZWxfZnJvbSwgcmVsX3RvKToKKyAgICAgICAgcmVsX2Zyb20gPSByZWxfZnJv
bS5lbmNvZGUoJ3V0Zi04JykKKyAgICAgICAgcmVsX3RvID0gcmVsX3RvLmVuY29kZSgndXRmLTgn
KQogICAgICAgICBzZWxmLl9iYWNraW5nX3RyYW5zcG9ydC5yZW5hbWUocmVsX2Zyb20sIHJlbF90
bykKIAogICAgIGRlZiBkb19ybWRpcihzZWxmLCByZWxwYXRoKToKKyAgICAgICAgcmVscGF0aCA9
IHJlbHBhdGguZW5jb2RlKCd1dGYtOCcpCiAgICAgICAgIHNlbGYuX2JhY2tpbmdfdHJhbnNwb3J0
LnJtZGlyKHJlbHBhdGgpCiAKICAgICBkZWYgZG9fc3RhdChzZWxmLCByZWxwYXRoKToKKyAgICAg
ICAgcmVscGF0aCA9IHJlbHBhdGguZW5jb2RlKCd1dGYtOCcpCiAgICAgICAgIHN0YXQgPSBzZWxm
Ll9iYWNraW5nX3RyYW5zcG9ydC5zdGF0KHJlbHBhdGgpCiAgICAgICAgIHJldHVybiBTbWFydFNl
cnZlclJlc3BvbnNlKCgnc3RhdCcsIHN0cihzdGF0LnN0X3NpemUpLCBvY3Qoc3RhdC5zdF9tb2Rl
KSkpCiAgICAgICAgIAoK
# revision id: andrew.bennetts at canonical.com-20061012085801-36b60463388ea0e7
# sha1: fe0d697cf51ffe0fd9e6a99b58a487493faa73d0
# inventory sha1: 07d54dc8c33516287becb6384608ec00531d8204
# parent ids:
# andrew.bennetts at canonical.com-20061012063051-5efaeb5409f0dbad
# properties:
# branch-nick: smart server unicode
More information about the bazaar
mailing list