[MERGE] ChrootTransportDecorator
Andrew Bennetts
andrew at canonical.com
Fri Oct 13 07:56:53 BST 2006
This bundle adds a ChrootTransportDecorator. I use this in the latest revision
of my WSGI branch, so that the smart server won't provide a way to access any
file on your filesystem.
The bundle is relative to the MemoryTransport.abspath fix posted earlier.
-Andrew.
-------------- next part --------------
# Bazaar revision bundle v0.8
#
# message:
# Merge from 'memory transport abspath'.
# committer: Andrew Bennetts <andrew.bennetts at canonical.com>
# date: Fri 2006-10-13 15:44:24.796000004 +1000
=== added file bzrlib/transport/chroot.py // file-id:chroot.py-20061011104729-0
... us9mgm97z378vnt-1 // last-changed:andrew.bennetts at canonical.com-20061012060
... 928-e387650ef98b70f5
--- /dev/null
+++ bzrlib/transport/chroot.py
@@ -0,0 +1,136 @@
+# Copyright (C) 2006 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""Implementation of Transport that prevents access to locations above a set
+root.
+"""
+
+from bzrlib import errors, urlutils
+from bzrlib.transport.decorator import TransportDecorator, DecoratorServer
+
+
+class ChrootTransportDecorator(TransportDecorator):
+ """A decorator that can convert any transport to be chrooted.
+
+ This is requested via the 'chrooted+' prefix to get_transport().
+ """
+
+ def __init__(self, url, _decorated=None, chroot=None):
+ super(ChrootTransportDecorator, self).__init__(url,
+ _decorated=_decorated)
+ if chroot is None:
+ self.chroot_url = self._decorated.base
+ else:
+ self.chroot_url = chroot
+
+ @classmethod
+ def _get_url_prefix(self):
+ """Chroot transport decorators are invoked via 'chroot+'"""
+ return 'chroot+'
+
+ def _ensure_relpath_is_child(self, relpath):
+ abspath = self.abspath(relpath)
+ chroot_base = self._get_url_prefix() + self.chroot_url
+ real_relpath = urlutils.relative_url(chroot_base, abspath)
+ if real_relpath == '..' or real_relpath.startswith('../'):
+ raise errors.PathNotChild(relpath, self.chroot_url)
+
+ # decorated methods
+ def append_file(self, relpath, f, mode=None):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.append_file(self, relpath, f, mode=mode)
+
+ def append_bytes(self, relpath, bytes, mode=None):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.append_bytes(self, relpath, bytes, mode=mode)
+
+ def clone(self, offset=None):
+ self._ensure_relpath_is_child(offset)
+ return TransportDecorator.clone(self, offset)
+
+ def delete(self, relpath):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.delete(self, relpath)
+
+ def delete_tree(self, relpath):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.delete_tree(self, relpath)
+
+ def get(self, relpath):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.get(self, relpath)
+
+ def get_bytes(self, relpath):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.get_bytes(self, relpath)
+
+ def get(self, relpath):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.get(self, relpath)
+
+ def has(self, relpath):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.has(self, relpath)
+
+ def list_dir(self, relpath):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.list_dir(self, relpath)
+
+ def lock_read(self, relpath):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.lock_read(self, relpath)
+
+ def lock_write(self, relpath):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.lock_write(self, relpath)
+
+ def mkdir(self, relpath, mode=None):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.mkdir(self, relpath, mode=mode)
+
+ def put_bytes(self, relpath, bytes, mode=None):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.put_bytes(self, relpath, bytes, mode=mode)
+
+ def put_file(self, relpath, f, mode=None):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.put_file(self, relpath, f, mode=mode)
+
+ def rename(self, rel_from, rel_to):
+ self._ensure_relpath_is_child(rel_from)
+ self._ensure_relpath_is_child(rel_to)
+ return TransportDecorator.rename(self, rel_from, rel_to)
+
+ def rmdir(self, relpath):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.rmdir(self, relpath)
+
+ def stat(self, relpath):
+ self._ensure_relpath_is_child(relpath)
+ return TransportDecorator.stat(self, relpath)
+
+
+class ChrootServer(DecoratorServer):
+ """Server for the ReadonlyTransportDecorator for testing with."""
+
+ def get_decorator_class(self):
+ return ChrootTransportDecorator
+
+
+def get_test_permutations():
+ """Return the permutations to be used in testing."""
+ return [(ChrootTransportDecorator, ChrootServer),
+ ]
=== modified file NEWS // last-changed:andrew.bennetts at canonical.com-2006101206
... 0928-e387650ef98b70f5
--- NEWS
+++ NEWS
@@ -13,6 +13,10 @@
around a regex, which defers compilation until first use.
(John Arbash Meinel)
+ * New ``ChrootTransportDecorator``, accessible via the ``chroot+`` url
+ prefix. It disallows any access to locations above a set URL. (Andrew
+ Bennetts)
+
BUG FIXES:
* bzr branch/pull no longer complain about progress bar cleanup when
=== modified file bzrlib/tests/test_transport.py
--- bzrlib/tests/test_transport.py
+++ bzrlib/tests/test_transport.py
@@ -21,12 +21,15 @@
from cStringIO import StringIO
import bzrlib
-from bzrlib.errors import (NoSuchFile, FileExists,
- TransportNotPossible,
- ConnectionError,
- DependencyNotPresent,
- UnsupportedProtocol,
- )
+from bzrlib.errors import (
+ ConnectionError,
+ DependencyNotPresent,
+ FileExists,
+ NoSuchFile,
+ PathNotChild,
+ TransportNotPossible,
+ UnsupportedProtocol,
+ )
from bzrlib.tests import TestCase, TestCaseInTempDir
from bzrlib.transport import (_CoalescedOffset,
_get_protocol_handlers,
@@ -258,6 +261,88 @@
self.assertEqual(7, transport.stat('foo').st_size)
self.assertEqual(6, transport.stat('bar').st_size)
+
+class ChrootDecoratorTransportTest(TestCase):
+ """Chroot decoration specific tests."""
+
+ def test_construct(self):
+ from bzrlib.transport import chroot
+ transport = chroot.ChrootTransportDecorator('chroot+memory:///pathA/')
+ self.assertEqual('memory:///pathA/', transport.chroot_url)
+
+ transport = chroot.ChrootTransportDecorator(
+ 'chroot+memory:///path/B', chroot='memory:///path/')
+ self.assertEqual('memory:///path/', transport.chroot_url)
+
+ def test_append_file(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.append_file, '/foo', None)
+
+ def test_append_bytes(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.append_bytes, '/foo', 'bytes')
+
+ def test_clone(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.clone, '/foo')
+
+ def test_delete(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.delete, '/foo')
+
+ def test_delete_tree(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.delete_tree, '/foo')
+
+ def test_get(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.get, '/foo')
+
+ def test_get_bytes(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.get_bytes, '/foo')
+
+ def test_has(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.has, '/foo')
+
+ def test_list_dir(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.list_dir, '/foo')
+
+ def test_lock_read(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.lock_read, '/foo')
+
+ def test_lock_write(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.lock_write, '/foo')
+
+ def test_mkdir(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.mkdir, '/foo')
+
+ def test_put_bytes(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.put_bytes, '/foo', 'bytes')
+
+ def test_put_file(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.put_file, '/foo', None)
+
+ def test_rename(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.rename, '/aaa', 'bbb')
+ self.assertRaises(PathNotChild, transport.rename, 'ccc', '/d')
+
+ def test_rmdir(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.rmdir, '/foo')
+
+ def test_stat(self):
+ transport = get_transport('chroot+file:///foo/bar')
+ self.assertRaises(PathNotChild, transport.stat, '/foo')
+
class ReadonlyDecoratorTransportTest(TestCase):
"""Readonly decoration specific tests."""
=== modified file bzrlib/tests/test_transport_implementations.py
--- bzrlib/tests/test_transport_implementations.py
+++ bzrlib/tests/test_transport_implementations.py
@@ -38,7 +38,7 @@
from bzrlib.symbol_versioning import zero_eleven
from bzrlib.tests import TestCaseInTempDir, TestSkipped
from bzrlib.tests.test_transport import TestTransportImplementation
-from bzrlib.transport import memory, smart
+from bzrlib.transport import memory, smart, chroot
import bzrlib.transport
@@ -94,7 +94,8 @@
def test_has_root_works(self):
current_transport = self.get_transport()
- # import pdb;pdb.set_trace()
+ if isinstance(current_transport, chroot.ChrootTransportDecorator):
+ raise TestSkipped("ChrootTransportDecorator disallows clone('..')")
self.assertTrue(current_transport.has('/'))
root = current_transport.clone('/')
self.assertTrue(root.has(''))
@@ -1012,6 +1013,8 @@
def test_clone(self):
# TODO: Test that clone moves up and down the filesystem
t1 = self.get_transport()
+ if isinstance(t1, chroot.ChrootTransportDecorator):
+ raise TestSkipped("ChrootTransportDecorator disallows clone('..')")
self.build_tree(['a', 'b/', 'b/c'], transport=t1)
@@ -1044,6 +1047,8 @@
def test_clone_to_root(self):
orig_transport = self.get_transport()
+ if isinstance(orig_transport, chroot.ChrootTransportDecorator):
+ raise TestSkipped("ChrootTransportDecorator disallows clone('..')")
# Repeatedly go up to a parent directory until we're at the root
# directory of this transport
root_transport = orig_transport
@@ -1072,6 +1077,8 @@
def test_clone_from_root(self):
"""At the root, cloning to a simple dir should just do string append."""
orig_transport = self.get_transport()
+ if isinstance(orig_transport, chroot.ChrootTransportDecorator):
+ raise TestSkipped("ChrootTransportDecorator disallows clone('/')")
root_transport = orig_transport.clone('/')
self.assertEqual(root_transport.base + '.bzr/',
root_transport.clone('.bzr').base)
@@ -1092,6 +1099,8 @@
def test_relpath_at_root(self):
t = self.get_transport()
+ if isinstance(t, chroot.ChrootTransportDecorator):
+ raise TestSkipped("ChrootTransportDecorator disallows clone('..')")
# clone all the way to the top
new_transport = t.clone('..')
while new_transport.base != t.base:
@@ -1107,6 +1116,8 @@
# that have aliasing problems like symlinks should go in backend
# specific test cases.
transport = self.get_transport()
+ if isinstance(transport, chroot.ChrootTransportDecorator):
+ raise TestSkipped("ChrootTransportDecorator disallows clone('..')")
self.assertEqual(transport.base + 'relpath',
transport.abspath('relpath'))
@@ -1131,6 +1142,8 @@
def test_abspath_at_root(self):
t = self.get_transport()
+ if isinstance(t, chroot.ChrootTransportDecorator):
+ raise TestSkipped("ChrootTransportDecorator disallows clone('..')")
# clone all the way to the top
new_transport = t.clone('..')
while new_transport.base != t.base:
@@ -1235,6 +1248,8 @@
# check that our server (whatever it is) is accessable reliably
# via get_transport and multiple connections share content.
transport = self.get_transport()
+ if isinstance(transport, chroot.ChrootTransportDecorator):
+ raise TestSkipped("ChrootTransportDecorator disallows clone('..')")
if transport.is_readonly():
return
transport.put_bytes('foo', 'bar')
=== modified file bzrlib/transport/__init__.py
--- bzrlib/transport/__init__.py
+++ bzrlib/transport/__init__.py
@@ -1170,6 +1170,8 @@
register_lazy_transport('ftp://', 'bzrlib.transport.ftp', 'FtpTransport')
register_lazy_transport('aftp://', 'bzrlib.transport.ftp', 'FtpTransport')
register_lazy_transport('memory://', 'bzrlib.transport.memory', 'MemoryTransport')
+register_lazy_transport('chroot+', 'bzrlib.transport.chroot',
+ 'ChrootTransportDecorator')
register_lazy_transport('readonly+', 'bzrlib.transport.readonly', 'ReadonlyTransportDecorator')
register_lazy_transport('fakenfs+', 'bzrlib.transport.fakenfs', 'FakeNFSTransportDecorator')
register_lazy_transport('vfat+',
# revision id: andrew.bennetts at canonical.com-20061013054424-f5728f4a9d1dd739
# sha1: 71a2bafc348d72fdeeb37545f8d369cd6d432953
# inventory sha1: 6e32a30deb48b99d33203ea46e2bf8c4e2f832ff
# parent ids:
# andrew.bennetts at canonical.com-20061012060928-e387650ef98b70f5
# andrew.bennetts at canonical.com-20061013052902-60a2d663ee8d494b
# base id: andrew.bennetts at canonical.com-20061013052902-60a2d663ee8d494b
# properties:
# branch-nick: chroot decorator
# message:
# Add ChrootTransportDecorator.
# committer: Andrew Bennetts <andrew.bennetts at canonical.com>
# date: Thu 2006-10-12 16:09:28.492000103 +1000
=== added file bzrlib/transport/chroot.py // file-id:chroot.py-20061011104729-0
... us9mgm97z378vnt-1 // encoding:base64
LS0tIC9kZXYvbnVsbAorKysgYnpybGliL3RyYW5zcG9ydC9jaHJvb3QucHkKQEAgLTAsMCArMSwx
MzYgQEAKKyMgQ29weXJpZ2h0IChDKSAyMDA2IENhbm9uaWNhbCBMdGQKKyMKKyMgVGhpcyBwcm9n
cmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2Rp
ZnkKKyMgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5z
ZSBhcyBwdWJsaXNoZWQgYnkKKyMgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVy
IHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKKyMgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0
ZXIgdmVyc2lvbi4KKyMKKyMgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3Bl
IHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCisjIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0
aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisjIE1FUkNIQU5UQUJJTElUWSBvciBG
SVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKKyMgR05VIEdlbmVyYWwg
UHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KKyMKKyMgWW91IHNob3VsZCBoYXZlIHJl
Y2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKKyMgYWxvbmcg
d2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKKyMg
Rm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEg
IDAyMTExLTEzMDcgIFVTQQorCisiIiJJbXBsZW1lbnRhdGlvbiBvZiBUcmFuc3BvcnQgdGhhdCBw
cmV2ZW50cyBhY2Nlc3MgdG8gbG9jYXRpb25zIGFib3ZlIGEgc2V0Cityb290LgorIiIiCisKK2Zy
b20gYnpybGliIGltcG9ydCBlcnJvcnMsIHVybHV0aWxzCitmcm9tIGJ6cmxpYi50cmFuc3BvcnQu
ZGVjb3JhdG9yIGltcG9ydCBUcmFuc3BvcnREZWNvcmF0b3IsIERlY29yYXRvclNlcnZlcgorCisK
K2NsYXNzIENocm9vdFRyYW5zcG9ydERlY29yYXRvcihUcmFuc3BvcnREZWNvcmF0b3IpOgorICAg
ICIiIkEgZGVjb3JhdG9yIHRoYXQgY2FuIGNvbnZlcnQgYW55IHRyYW5zcG9ydCB0byBiZSBjaHJv
b3RlZC4KKworICAgIFRoaXMgaXMgcmVxdWVzdGVkIHZpYSB0aGUgJ2Nocm9vdGVkKycgcHJlZml4
IHRvIGdldF90cmFuc3BvcnQoKS4KKyAgICAiIiIKKworICAgIGRlZiBfX2luaXRfXyhzZWxmLCB1
cmwsIF9kZWNvcmF0ZWQ9Tm9uZSwgY2hyb290PU5vbmUpOgorICAgICAgICBzdXBlcihDaHJvb3RU
cmFuc3BvcnREZWNvcmF0b3IsIHNlbGYpLl9faW5pdF9fKHVybCwKKyAgICAgICAgICAgICAgICBf
ZGVjb3JhdGVkPV9kZWNvcmF0ZWQpCisgICAgICAgIGlmIGNocm9vdCBpcyBOb25lOgorICAgICAg
ICAgICAgc2VsZi5jaHJvb3RfdXJsID0gc2VsZi5fZGVjb3JhdGVkLmJhc2UKKyAgICAgICAgZWxz
ZToKKyAgICAgICAgICAgIHNlbGYuY2hyb290X3VybCA9IGNocm9vdAorCisgICAgQGNsYXNzbWV0
aG9kCisgICAgZGVmIF9nZXRfdXJsX3ByZWZpeChzZWxmKToKKyAgICAgICAgIiIiQ2hyb290IHRy
YW5zcG9ydCBkZWNvcmF0b3JzIGFyZSBpbnZva2VkIHZpYSAnY2hyb290KyciIiIKKyAgICAgICAg
cmV0dXJuICdjaHJvb3QrJworCisgICAgZGVmIF9lbnN1cmVfcmVscGF0aF9pc19jaGlsZChzZWxm
LCByZWxwYXRoKToKKyAgICAgICAgYWJzcGF0aCA9IHNlbGYuYWJzcGF0aChyZWxwYXRoKQorICAg
ICAgICBjaHJvb3RfYmFzZSA9IHNlbGYuX2dldF91cmxfcHJlZml4KCkgKyBzZWxmLmNocm9vdF91
cmwKKyAgICAgICAgcmVhbF9yZWxwYXRoID0gdXJsdXRpbHMucmVsYXRpdmVfdXJsKGNocm9vdF9i
YXNlLCBhYnNwYXRoKQorICAgICAgICBpZiByZWFsX3JlbHBhdGggPT0gJy4uJyBvciByZWFsX3Jl
bHBhdGguc3RhcnRzd2l0aCgnLi4vJyk6CisgICAgICAgICAgICByYWlzZSBlcnJvcnMuUGF0aE5v
dENoaWxkKHJlbHBhdGgsIHNlbGYuY2hyb290X3VybCkKKworICAgICMgZGVjb3JhdGVkIG1ldGhv
ZHMKKyAgICBkZWYgYXBwZW5kX2ZpbGUoc2VsZiwgcmVscGF0aCwgZiwgbW9kZT1Ob25lKToKKyAg
ICAgICAgc2VsZi5fZW5zdXJlX3JlbHBhdGhfaXNfY2hpbGQocmVscGF0aCkKKyAgICAgICAgcmV0
dXJuIFRyYW5zcG9ydERlY29yYXRvci5hcHBlbmRfZmlsZShzZWxmLCByZWxwYXRoLCBmLCBtb2Rl
PW1vZGUpCisKKyAgICBkZWYgYXBwZW5kX2J5dGVzKHNlbGYsIHJlbHBhdGgsIGJ5dGVzLCBtb2Rl
PU5vbmUpOgorICAgICAgICBzZWxmLl9lbnN1cmVfcmVscGF0aF9pc19jaGlsZChyZWxwYXRoKQor
ICAgICAgICByZXR1cm4gVHJhbnNwb3J0RGVjb3JhdG9yLmFwcGVuZF9ieXRlcyhzZWxmLCByZWxw
YXRoLCBieXRlcywgbW9kZT1tb2RlKQorCisgICAgZGVmIGNsb25lKHNlbGYsIG9mZnNldD1Ob25l
KToKKyAgICAgICAgc2VsZi5fZW5zdXJlX3JlbHBhdGhfaXNfY2hpbGQob2Zmc2V0KQorICAgICAg
ICByZXR1cm4gVHJhbnNwb3J0RGVjb3JhdG9yLmNsb25lKHNlbGYsIG9mZnNldCkKKworICAgIGRl
ZiBkZWxldGUoc2VsZiwgcmVscGF0aCk6CisgICAgICAgIHNlbGYuX2Vuc3VyZV9yZWxwYXRoX2lz
X2NoaWxkKHJlbHBhdGgpCisgICAgICAgIHJldHVybiBUcmFuc3BvcnREZWNvcmF0b3IuZGVsZXRl
KHNlbGYsIHJlbHBhdGgpCisKKyAgICBkZWYgZGVsZXRlX3RyZWUoc2VsZiwgcmVscGF0aCk6Cisg
ICAgICAgIHNlbGYuX2Vuc3VyZV9yZWxwYXRoX2lzX2NoaWxkKHJlbHBhdGgpCisgICAgICAgIHJl
dHVybiBUcmFuc3BvcnREZWNvcmF0b3IuZGVsZXRlX3RyZWUoc2VsZiwgcmVscGF0aCkKKworICAg
IGRlZiBnZXQoc2VsZiwgcmVscGF0aCk6CisgICAgICAgIHNlbGYuX2Vuc3VyZV9yZWxwYXRoX2lz
X2NoaWxkKHJlbHBhdGgpCisgICAgICAgIHJldHVybiBUcmFuc3BvcnREZWNvcmF0b3IuZ2V0KHNl
bGYsIHJlbHBhdGgpCisKKyAgICBkZWYgZ2V0X2J5dGVzKHNlbGYsIHJlbHBhdGgpOgorICAgICAg
ICBzZWxmLl9lbnN1cmVfcmVscGF0aF9pc19jaGlsZChyZWxwYXRoKQorICAgICAgICByZXR1cm4g
VHJhbnNwb3J0RGVjb3JhdG9yLmdldF9ieXRlcyhzZWxmLCByZWxwYXRoKQorCisgICAgZGVmIGdl
dChzZWxmLCByZWxwYXRoKToKKyAgICAgICAgc2VsZi5fZW5zdXJlX3JlbHBhdGhfaXNfY2hpbGQo
cmVscGF0aCkKKyAgICAgICAgcmV0dXJuIFRyYW5zcG9ydERlY29yYXRvci5nZXQoc2VsZiwgcmVs
cGF0aCkKKworICAgIGRlZiBoYXMoc2VsZiwgcmVscGF0aCk6CisgICAgICAgIHNlbGYuX2Vuc3Vy
ZV9yZWxwYXRoX2lzX2NoaWxkKHJlbHBhdGgpCisgICAgICAgIHJldHVybiBUcmFuc3BvcnREZWNv
cmF0b3IuaGFzKHNlbGYsIHJlbHBhdGgpCisKKyAgICBkZWYgbGlzdF9kaXIoc2VsZiwgcmVscGF0
aCk6CisgICAgICAgIHNlbGYuX2Vuc3VyZV9yZWxwYXRoX2lzX2NoaWxkKHJlbHBhdGgpCisgICAg
ICAgIHJldHVybiBUcmFuc3BvcnREZWNvcmF0b3IubGlzdF9kaXIoc2VsZiwgcmVscGF0aCkKKwor
ICAgIGRlZiBsb2NrX3JlYWQoc2VsZiwgcmVscGF0aCk6CisgICAgICAgIHNlbGYuX2Vuc3VyZV9y
ZWxwYXRoX2lzX2NoaWxkKHJlbHBhdGgpCisgICAgICAgIHJldHVybiBUcmFuc3BvcnREZWNvcmF0
b3IubG9ja19yZWFkKHNlbGYsIHJlbHBhdGgpCisKKyAgICBkZWYgbG9ja193cml0ZShzZWxmLCBy
ZWxwYXRoKToKKyAgICAgICAgc2VsZi5fZW5zdXJlX3JlbHBhdGhfaXNfY2hpbGQocmVscGF0aCkK
KyAgICAgICAgcmV0dXJuIFRyYW5zcG9ydERlY29yYXRvci5sb2NrX3dyaXRlKHNlbGYsIHJlbHBh
dGgpCisKKyAgICBkZWYgbWtkaXIoc2VsZiwgcmVscGF0aCwgbW9kZT1Ob25lKToKKyAgICAgICAg
c2VsZi5fZW5zdXJlX3JlbHBhdGhfaXNfY2hpbGQocmVscGF0aCkKKyAgICAgICAgcmV0dXJuIFRy
YW5zcG9ydERlY29yYXRvci5ta2RpcihzZWxmLCByZWxwYXRoLCBtb2RlPW1vZGUpCisKKyAgICBk
ZWYgcHV0X2J5dGVzKHNlbGYsIHJlbHBhdGgsIGJ5dGVzLCBtb2RlPU5vbmUpOgorICAgICAgICBz
ZWxmLl9lbnN1cmVfcmVscGF0aF9pc19jaGlsZChyZWxwYXRoKQorICAgICAgICByZXR1cm4gVHJh
bnNwb3J0RGVjb3JhdG9yLnB1dF9ieXRlcyhzZWxmLCByZWxwYXRoLCBieXRlcywgbW9kZT1tb2Rl
KQorCisgICAgZGVmIHB1dF9maWxlKHNlbGYsIHJlbHBhdGgsIGYsIG1vZGU9Tm9uZSk6CisgICAg
ICAgIHNlbGYuX2Vuc3VyZV9yZWxwYXRoX2lzX2NoaWxkKHJlbHBhdGgpCisgICAgICAgIHJldHVy
biBUcmFuc3BvcnREZWNvcmF0b3IucHV0X2ZpbGUoc2VsZiwgcmVscGF0aCwgZiwgbW9kZT1tb2Rl
KQorCisgICAgZGVmIHJlbmFtZShzZWxmLCByZWxfZnJvbSwgcmVsX3RvKToKKyAgICAgICAgc2Vs
Zi5fZW5zdXJlX3JlbHBhdGhfaXNfY2hpbGQocmVsX2Zyb20pCisgICAgICAgIHNlbGYuX2Vuc3Vy
ZV9yZWxwYXRoX2lzX2NoaWxkKHJlbF90bykKKyAgICAgICAgcmV0dXJuIFRyYW5zcG9ydERlY29y
YXRvci5yZW5hbWUoc2VsZiwgcmVsX2Zyb20sIHJlbF90bykKKworICAgIGRlZiBybWRpcihzZWxm
LCByZWxwYXRoKToKKyAgICAgICAgc2VsZi5fZW5zdXJlX3JlbHBhdGhfaXNfY2hpbGQocmVscGF0
aCkKKyAgICAgICAgcmV0dXJuIFRyYW5zcG9ydERlY29yYXRvci5ybWRpcihzZWxmLCByZWxwYXRo
KQorCisgICAgZGVmIHN0YXQoc2VsZiwgcmVscGF0aCk6CisgICAgICAgIHNlbGYuX2Vuc3VyZV9y
ZWxwYXRoX2lzX2NoaWxkKHJlbHBhdGgpCisgICAgICAgIHJldHVybiBUcmFuc3BvcnREZWNvcmF0
b3Iuc3RhdChzZWxmLCByZWxwYXRoKQorCisKK2NsYXNzIENocm9vdFNlcnZlcihEZWNvcmF0b3JT
ZXJ2ZXIpOgorICAgICIiIlNlcnZlciBmb3IgdGhlIFJlYWRvbmx5VHJhbnNwb3J0RGVjb3JhdG9y
IGZvciB0ZXN0aW5nIHdpdGguIiIiCisKKyAgICBkZWYgZ2V0X2RlY29yYXRvcl9jbGFzcyhzZWxm
KToKKyAgICAgICAgcmV0dXJuIENocm9vdFRyYW5zcG9ydERlY29yYXRvcgorCisKK2RlZiBnZXRf
dGVzdF9wZXJtdXRhdGlvbnMoKToKKyAgICAiIiJSZXR1cm4gdGhlIHBlcm11dGF0aW9ucyB0byBi
ZSB1c2VkIGluIHRlc3RpbmcuIiIiCisgICAgcmV0dXJuIFsoQ2hyb290VHJhbnNwb3J0RGVjb3Jh
dG9yLCBDaHJvb3RTZXJ2ZXIpLAorICAgICAgICAgICAgXQoK
=== modified file NEWS // encoding:base64
LS0tIE5FV1MKKysrIE5FV1MKQEAgLTEzLDYgKzEzLDEwIEBACiAgICAgICBhcm91bmQgYSByZWdl
eCwgd2hpY2ggZGVmZXJzIGNvbXBpbGF0aW9uIHVudGlsIGZpcnN0IHVzZS4gCiAgICAgICAoSm9o
biBBcmJhc2ggTWVpbmVsKQogCisgICAgKiBOZXcgYGBDaHJvb3RUcmFuc3BvcnREZWNvcmF0b3Jg
YCwgYWNjZXNzaWJsZSB2aWEgdGhlIGBgY2hyb290K2BgIHVybAorICAgICAgcHJlZml4LiAgSXQg
ZGlzYWxsb3dzIGFueSBhY2Nlc3MgdG8gbG9jYXRpb25zIGFib3ZlIGEgc2V0IFVSTC4gIChBbmRy
ZXcKKyAgICAgIEJlbm5ldHRzKQorCiAgIEJVRyBGSVhFUzoKIAogICAgICogYnpyIGJyYW5jaC9w
dWxsIG5vIGxvbmdlciBjb21wbGFpbiBhYm91dCBwcm9ncmVzcyBiYXIgY2xlYW51cCB3aGVuCgo=
=== modified file bzrlib/tests/test_transport.py // encoding:base64
LS0tIGJ6cmxpYi90ZXN0cy90ZXN0X3RyYW5zcG9ydC5weQorKysgYnpybGliL3Rlc3RzL3Rlc3Rf
dHJhbnNwb3J0LnB5CkBAIC0yMSwxMiArMjEsMTUgQEAKIGZyb20gY1N0cmluZ0lPIGltcG9ydCBT
dHJpbmdJTwogCiBpbXBvcnQgYnpybGliCi1mcm9tIGJ6cmxpYi5lcnJvcnMgaW1wb3J0IChOb1N1
Y2hGaWxlLCBGaWxlRXhpc3RzLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNwb3J0
Tm90UG9zc2libGUsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICBDb25uZWN0aW9uRXJyb3Is
Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICBEZXBlbmRlbmN5Tm90UHJlc2VudCwKLSAgICAg
ICAgICAgICAgICAgICAgICAgICAgIFVuc3VwcG9ydGVkUHJvdG9jb2wsCi0gICAgICAgICAgICAg
ICAgICAgICAgICAgICApCitmcm9tIGJ6cmxpYi5lcnJvcnMgaW1wb3J0ICgKKyAgICBDb25uZWN0
aW9uRXJyb3IsCisgICAgRGVwZW5kZW5jeU5vdFByZXNlbnQsCisgICAgRmlsZUV4aXN0cywKKyAg
ICBOb1N1Y2hGaWxlLAorICAgIFBhdGhOb3RDaGlsZCwKKyAgICBUcmFuc3BvcnROb3RQb3NzaWJs
ZSwKKyAgICBVbnN1cHBvcnRlZFByb3RvY29sLAorICAgICkKIGZyb20gYnpybGliLnRlc3RzIGlt
cG9ydCBUZXN0Q2FzZSwgVGVzdENhc2VJblRlbXBEaXIKIGZyb20gYnpybGliLnRyYW5zcG9ydCBp
bXBvcnQgKF9Db2FsZXNjZWRPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBf
Z2V0X3Byb3RvY29sX2hhbmRsZXJzLApAQCAtMjU3LDYgKzI2MCw4OCBAQAogICAgICAgICBzZWxm
LmFzc2VydEVxdWFsKDcsIHRyYW5zcG9ydC5zdGF0KCdmb28nKS5zdF9zaXplKQogICAgICAgICBz
ZWxmLmFzc2VydEVxdWFsKDYsIHRyYW5zcG9ydC5zdGF0KCdiYXInKS5zdF9zaXplKQogCisKK2Ns
YXNzIENocm9vdERlY29yYXRvclRyYW5zcG9ydFRlc3QoVGVzdENhc2UpOgorICAgICIiIkNocm9v
dCBkZWNvcmF0aW9uIHNwZWNpZmljIHRlc3RzLiIiIgorCisgICAgZGVmIHRlc3RfY29uc3RydWN0
KHNlbGYpOgorICAgICAgICBmcm9tIGJ6cmxpYi50cmFuc3BvcnQgaW1wb3J0IGNocm9vdAorICAg
ICAgICB0cmFuc3BvcnQgPSBjaHJvb3QuQ2hyb290VHJhbnNwb3J0RGVjb3JhdG9yKCdjaHJvb3Qr
bWVtb3J5Oi8vL3BhdGhBLycpCisgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoJ21lbW9yeTovLy9w
YXRoQS8nLCB0cmFuc3BvcnQuY2hyb290X3VybCkKKworICAgICAgICB0cmFuc3BvcnQgPSBjaHJv
b3QuQ2hyb290VHJhbnNwb3J0RGVjb3JhdG9yKAorICAgICAgICAgICAgJ2Nocm9vdCttZW1vcnk6
Ly8vcGF0aC9CJywgY2hyb290PSdtZW1vcnk6Ly8vcGF0aC8nKQorICAgICAgICBzZWxmLmFzc2Vy
dEVxdWFsKCdtZW1vcnk6Ly8vcGF0aC8nLCB0cmFuc3BvcnQuY2hyb290X3VybCkKKworICAgIGRl
ZiB0ZXN0X2FwcGVuZF9maWxlKHNlbGYpOgorICAgICAgICB0cmFuc3BvcnQgPSBnZXRfdHJhbnNw
b3J0KCdjaHJvb3QrZmlsZTovLy9mb28vYmFyJykKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMo
UGF0aE5vdENoaWxkLCB0cmFuc3BvcnQuYXBwZW5kX2ZpbGUsICcvZm9vJywgTm9uZSkKKworICAg
IGRlZiB0ZXN0X2FwcGVuZF9ieXRlcyhzZWxmKToKKyAgICAgICAgdHJhbnNwb3J0ID0gZ2V0X3Ry
YW5zcG9ydCgnY2hyb290K2ZpbGU6Ly8vZm9vL2JhcicpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFp
c2VzKFBhdGhOb3RDaGlsZCwgdHJhbnNwb3J0LmFwcGVuZF9ieXRlcywgJy9mb28nLCAnYnl0ZXMn
KQorCisgICAgZGVmIHRlc3RfY2xvbmUoc2VsZik6CisgICAgICAgIHRyYW5zcG9ydCA9IGdldF90
cmFuc3BvcnQoJ2Nocm9vdCtmaWxlOi8vL2Zvby9iYXInKQorICAgICAgICBzZWxmLmFzc2VydFJh
aXNlcyhQYXRoTm90Q2hpbGQsIHRyYW5zcG9ydC5jbG9uZSwgJy9mb28nKQorCisgICAgZGVmIHRl
c3RfZGVsZXRlKHNlbGYpOgorICAgICAgICB0cmFuc3BvcnQgPSBnZXRfdHJhbnNwb3J0KCdjaHJv
b3QrZmlsZTovLy9mb28vYmFyJykKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoUGF0aE5vdENo
aWxkLCB0cmFuc3BvcnQuZGVsZXRlLCAnL2ZvbycpCisKKyAgICBkZWYgdGVzdF9kZWxldGVfdHJl
ZShzZWxmKToKKyAgICAgICAgdHJhbnNwb3J0ID0gZ2V0X3RyYW5zcG9ydCgnY2hyb290K2ZpbGU6
Ly8vZm9vL2JhcicpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFBhdGhOb3RDaGlsZCwgdHJh
bnNwb3J0LmRlbGV0ZV90cmVlLCAnL2ZvbycpCisKKyAgICBkZWYgdGVzdF9nZXQoc2VsZik6Cisg
ICAgICAgIHRyYW5zcG9ydCA9IGdldF90cmFuc3BvcnQoJ2Nocm9vdCtmaWxlOi8vL2Zvby9iYXIn
KQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhQYXRoTm90Q2hpbGQsIHRyYW5zcG9ydC5nZXQs
ICcvZm9vJykKKworICAgIGRlZiB0ZXN0X2dldF9ieXRlcyhzZWxmKToKKyAgICAgICAgdHJhbnNw
b3J0ID0gZ2V0X3RyYW5zcG9ydCgnY2hyb290K2ZpbGU6Ly8vZm9vL2JhcicpCisgICAgICAgIHNl
bGYuYXNzZXJ0UmFpc2VzKFBhdGhOb3RDaGlsZCwgdHJhbnNwb3J0LmdldF9ieXRlcywgJy9mb28n
KQorCisgICAgZGVmIHRlc3RfaGFzKHNlbGYpOgorICAgICAgICB0cmFuc3BvcnQgPSBnZXRfdHJh
bnNwb3J0KCdjaHJvb3QrZmlsZTovLy9mb28vYmFyJykKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlz
ZXMoUGF0aE5vdENoaWxkLCB0cmFuc3BvcnQuaGFzLCAnL2ZvbycpCisKKyAgICBkZWYgdGVzdF9s
aXN0X2RpcihzZWxmKToKKyAgICAgICAgdHJhbnNwb3J0ID0gZ2V0X3RyYW5zcG9ydCgnY2hyb290
K2ZpbGU6Ly8vZm9vL2JhcicpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFBhdGhOb3RDaGls
ZCwgdHJhbnNwb3J0Lmxpc3RfZGlyLCAnL2ZvbycpCisKKyAgICBkZWYgdGVzdF9sb2NrX3JlYWQo
c2VsZik6CisgICAgICAgIHRyYW5zcG9ydCA9IGdldF90cmFuc3BvcnQoJ2Nocm9vdCtmaWxlOi8v
L2Zvby9iYXInKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhQYXRoTm90Q2hpbGQsIHRyYW5z
cG9ydC5sb2NrX3JlYWQsICcvZm9vJykKKworICAgIGRlZiB0ZXN0X2xvY2tfd3JpdGUoc2VsZik6
CisgICAgICAgIHRyYW5zcG9ydCA9IGdldF90cmFuc3BvcnQoJ2Nocm9vdCtmaWxlOi8vL2Zvby9i
YXInKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhQYXRoTm90Q2hpbGQsIHRyYW5zcG9ydC5s
b2NrX3dyaXRlLCAnL2ZvbycpCisKKyAgICBkZWYgdGVzdF9ta2RpcihzZWxmKToKKyAgICAgICAg
dHJhbnNwb3J0ID0gZ2V0X3RyYW5zcG9ydCgnY2hyb290K2ZpbGU6Ly8vZm9vL2JhcicpCisgICAg
ICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFBhdGhOb3RDaGlsZCwgdHJhbnNwb3J0Lm1rZGlyLCAnL2Zv
bycpCisKKyAgICBkZWYgdGVzdF9wdXRfYnl0ZXMoc2VsZik6CisgICAgICAgIHRyYW5zcG9ydCA9
IGdldF90cmFuc3BvcnQoJ2Nocm9vdCtmaWxlOi8vL2Zvby9iYXInKQorICAgICAgICBzZWxmLmFz
c2VydFJhaXNlcyhQYXRoTm90Q2hpbGQsIHRyYW5zcG9ydC5wdXRfYnl0ZXMsICcvZm9vJywgJ2J5
dGVzJykKKworICAgIGRlZiB0ZXN0X3B1dF9maWxlKHNlbGYpOgorICAgICAgICB0cmFuc3BvcnQg
PSBnZXRfdHJhbnNwb3J0KCdjaHJvb3QrZmlsZTovLy9mb28vYmFyJykKKyAgICAgICAgc2VsZi5h
c3NlcnRSYWlzZXMoUGF0aE5vdENoaWxkLCB0cmFuc3BvcnQucHV0X2ZpbGUsICcvZm9vJywgTm9u
ZSkKKworICAgIGRlZiB0ZXN0X3JlbmFtZShzZWxmKToKKyAgICAgICAgdHJhbnNwb3J0ID0gZ2V0
X3RyYW5zcG9ydCgnY2hyb290K2ZpbGU6Ly8vZm9vL2JhcicpCisgICAgICAgIHNlbGYuYXNzZXJ0
UmFpc2VzKFBhdGhOb3RDaGlsZCwgdHJhbnNwb3J0LnJlbmFtZSwgJy9hYWEnLCAnYmJiJykKKyAg
ICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoUGF0aE5vdENoaWxkLCB0cmFuc3BvcnQucmVuYW1lLCAn
Y2NjJywgJy9kJykKKworICAgIGRlZiB0ZXN0X3JtZGlyKHNlbGYpOgorICAgICAgICB0cmFuc3Bv
cnQgPSBnZXRfdHJhbnNwb3J0KCdjaHJvb3QrZmlsZTovLy9mb28vYmFyJykKKyAgICAgICAgc2Vs
Zi5hc3NlcnRSYWlzZXMoUGF0aE5vdENoaWxkLCB0cmFuc3BvcnQucm1kaXIsICcvZm9vJykKKwor
ICAgIGRlZiB0ZXN0X3N0YXQoc2VsZik6CisgICAgICAgIHRyYW5zcG9ydCA9IGdldF90cmFuc3Bv
cnQoJ2Nocm9vdCtmaWxlOi8vL2Zvby9iYXInKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhQ
YXRoTm90Q2hpbGQsIHRyYW5zcG9ydC5zdGF0LCAnL2ZvbycpCisKICAgICAgICAgCiBjbGFzcyBS
ZWFkb25seURlY29yYXRvclRyYW5zcG9ydFRlc3QoVGVzdENhc2UpOgogICAgICIiIlJlYWRvbmx5
IGRlY29yYXRpb24gc3BlY2lmaWMgdGVzdHMuIiIiCgo=
=== modified file bzrlib/tests/test_transport_implementations.py // encoding:ba
... se64
LS0tIGJ6cmxpYi90ZXN0cy90ZXN0X3RyYW5zcG9ydF9pbXBsZW1lbnRhdGlvbnMucHkKKysrIGJ6
cmxpYi90ZXN0cy90ZXN0X3RyYW5zcG9ydF9pbXBsZW1lbnRhdGlvbnMucHkKQEAgLTM4LDcgKzM4
LDcgQEAKIGZyb20gYnpybGliLnN5bWJvbF92ZXJzaW9uaW5nIGltcG9ydCB6ZXJvX2VsZXZlbgog
ZnJvbSBienJsaWIudGVzdHMgaW1wb3J0IFRlc3RDYXNlSW5UZW1wRGlyLCBUZXN0U2tpcHBlZAog
ZnJvbSBienJsaWIudGVzdHMudGVzdF90cmFuc3BvcnQgaW1wb3J0IFRlc3RUcmFuc3BvcnRJbXBs
ZW1lbnRhdGlvbgotZnJvbSBienJsaWIudHJhbnNwb3J0IGltcG9ydCBtZW1vcnksIHNtYXJ0Citm
cm9tIGJ6cmxpYi50cmFuc3BvcnQgaW1wb3J0IG1lbW9yeSwgc21hcnQsIGNocm9vdAogaW1wb3J0
IGJ6cmxpYi50cmFuc3BvcnQKIAogCkBAIC05NCw3ICs5NCw4IEBACiAKICAgICBkZWYgdGVzdF9o
YXNfcm9vdF93b3JrcyhzZWxmKToKICAgICAgICAgY3VycmVudF90cmFuc3BvcnQgPSBzZWxmLmdl
dF90cmFuc3BvcnQoKQotICAgICAgICAjIGltcG9ydCBwZGI7cGRiLnNldF90cmFjZSgpCisgICAg
ICAgIGlmIGlzaW5zdGFuY2UoY3VycmVudF90cmFuc3BvcnQsIGNocm9vdC5DaHJvb3RUcmFuc3Bv
cnREZWNvcmF0b3IpOgorICAgICAgICAgICAgcmFpc2UgVGVzdFNraXBwZWQoIkNocm9vdFRyYW5z
cG9ydERlY29yYXRvciBkaXNhbGxvd3MgY2xvbmUoJy4uJykiKQogICAgICAgICBzZWxmLmFzc2Vy
dFRydWUoY3VycmVudF90cmFuc3BvcnQuaGFzKCcvJykpCiAgICAgICAgIHJvb3QgPSBjdXJyZW50
X3RyYW5zcG9ydC5jbG9uZSgnLycpCiAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyb290Lmhhcygn
JykpCkBAIC0xMDEyLDYgKzEwMTMsOCBAQAogICAgIGRlZiB0ZXN0X2Nsb25lKHNlbGYpOgogICAg
ICAgICAjIFRPRE86IFRlc3QgdGhhdCBjbG9uZSBtb3ZlcyB1cCBhbmQgZG93biB0aGUgZmlsZXN5
c3RlbQogICAgICAgICB0MSA9IHNlbGYuZ2V0X3RyYW5zcG9ydCgpCisgICAgICAgIGlmIGlzaW5z
dGFuY2UodDEsIGNocm9vdC5DaHJvb3RUcmFuc3BvcnREZWNvcmF0b3IpOgorICAgICAgICAgICAg
cmFpc2UgVGVzdFNraXBwZWQoIkNocm9vdFRyYW5zcG9ydERlY29yYXRvciBkaXNhbGxvd3MgY2xv
bmUoJy4uJykiKQogCiAgICAgICAgIHNlbGYuYnVpbGRfdHJlZShbJ2EnLCAnYi8nLCAnYi9jJ10s
IHRyYW5zcG9ydD10MSkKIApAQCAtMTA0NCw2ICsxMDQ3LDggQEAKIAogICAgIGRlZiB0ZXN0X2Ns
b25lX3RvX3Jvb3Qoc2VsZik6CiAgICAgICAgIG9yaWdfdHJhbnNwb3J0ID0gc2VsZi5nZXRfdHJh
bnNwb3J0KCkKKyAgICAgICAgaWYgaXNpbnN0YW5jZShvcmlnX3RyYW5zcG9ydCwgY2hyb290LkNo
cm9vdFRyYW5zcG9ydERlY29yYXRvcik6CisgICAgICAgICAgICByYWlzZSBUZXN0U2tpcHBlZCgi
Q2hyb290VHJhbnNwb3J0RGVjb3JhdG9yIGRpc2FsbG93cyBjbG9uZSgnLi4nKSIpCiAgICAgICAg
ICMgUmVwZWF0ZWRseSBnbyB1cCB0byBhIHBhcmVudCBkaXJlY3RvcnkgdW50aWwgd2UncmUgYXQg
dGhlIHJvb3QKICAgICAgICAgIyBkaXJlY3Rvcnkgb2YgdGhpcyB0cmFuc3BvcnQKICAgICAgICAg
cm9vdF90cmFuc3BvcnQgPSBvcmlnX3RyYW5zcG9ydApAQCAtMTA3Miw2ICsxMDc3LDggQEAKICAg
ICBkZWYgdGVzdF9jbG9uZV9mcm9tX3Jvb3Qoc2VsZik6CiAgICAgICAgICIiIkF0IHRoZSByb290
LCBjbG9uaW5nIHRvIGEgc2ltcGxlIGRpciBzaG91bGQganVzdCBkbyBzdHJpbmcgYXBwZW5kLiIi
IgogICAgICAgICBvcmlnX3RyYW5zcG9ydCA9IHNlbGYuZ2V0X3RyYW5zcG9ydCgpCisgICAgICAg
IGlmIGlzaW5zdGFuY2Uob3JpZ190cmFuc3BvcnQsIGNocm9vdC5DaHJvb3RUcmFuc3BvcnREZWNv
cmF0b3IpOgorICAgICAgICAgICAgcmFpc2UgVGVzdFNraXBwZWQoIkNocm9vdFRyYW5zcG9ydERl
Y29yYXRvciBkaXNhbGxvd3MgY2xvbmUoJy8nKSIpCiAgICAgICAgIHJvb3RfdHJhbnNwb3J0ID0g
b3JpZ190cmFuc3BvcnQuY2xvbmUoJy8nKQogICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJvb3Rf
dHJhbnNwb3J0LmJhc2UgKyAnLmJ6ci8nLAogICAgICAgICAgICAgcm9vdF90cmFuc3BvcnQuY2xv
bmUoJy5ienInKS5iYXNlKQpAQCAtMTA5Miw2ICsxMDk5LDggQEAKIAogICAgIGRlZiB0ZXN0X3Jl
bHBhdGhfYXRfcm9vdChzZWxmKToKICAgICAgICAgdCA9IHNlbGYuZ2V0X3RyYW5zcG9ydCgpCisg
ICAgICAgIGlmIGlzaW5zdGFuY2UodCwgY2hyb290LkNocm9vdFRyYW5zcG9ydERlY29yYXRvcik6
CisgICAgICAgICAgICByYWlzZSBUZXN0U2tpcHBlZCgiQ2hyb290VHJhbnNwb3J0RGVjb3JhdG9y
IGRpc2FsbG93cyBjbG9uZSgnLi4nKSIpCiAgICAgICAgICMgY2xvbmUgYWxsIHRoZSB3YXkgdG8g
dGhlIHRvcAogICAgICAgICBuZXdfdHJhbnNwb3J0ID0gdC5jbG9uZSgnLi4nKQogICAgICAgICB3
aGlsZSBuZXdfdHJhbnNwb3J0LmJhc2UgIT0gdC5iYXNlOgpAQCAtMTEyOCw2ICsxMTM3LDggQEAK
IAogICAgIGRlZiB0ZXN0X2Fic3BhdGhfYXRfcm9vdChzZWxmKToKICAgICAgICAgdCA9IHNlbGYu
Z2V0X3RyYW5zcG9ydCgpCisgICAgICAgIGlmIGlzaW5zdGFuY2UodCwgY2hyb290LkNocm9vdFRy
YW5zcG9ydERlY29yYXRvcik6CisgICAgICAgICAgICByYWlzZSBUZXN0U2tpcHBlZCgiQ2hyb290
VHJhbnNwb3J0RGVjb3JhdG9yIGRpc2FsbG93cyBjbG9uZSgnLi4nKSIpCiAgICAgICAgICMgY2xv
bmUgYWxsIHRoZSB3YXkgdG8gdGhlIHRvcAogICAgICAgICBuZXdfdHJhbnNwb3J0ID0gdC5jbG9u
ZSgnLi4nKQogICAgICAgICB3aGlsZSBuZXdfdHJhbnNwb3J0LmJhc2UgIT0gdC5iYXNlOgpAQCAt
MTIzMiw2ICsxMjQzLDggQEAKICAgICAgICAgIyBjaGVjayB0aGF0IG91ciBzZXJ2ZXIgKHdoYXRl
dmVyIGl0IGlzKSBpcyBhY2Nlc3NhYmxlIHJlbGlhYmx5CiAgICAgICAgICMgdmlhIGdldF90cmFu
c3BvcnQgYW5kIG11bHRpcGxlIGNvbm5lY3Rpb25zIHNoYXJlIGNvbnRlbnQuCiAgICAgICAgIHRy
YW5zcG9ydCA9IHNlbGYuZ2V0X3RyYW5zcG9ydCgpCisgICAgICAgIGlmIGlzaW5zdGFuY2UodHJh
bnNwb3J0LCBjaHJvb3QuQ2hyb290VHJhbnNwb3J0RGVjb3JhdG9yKToKKyAgICAgICAgICAgIHJh
aXNlIFRlc3RTa2lwcGVkKCJDaHJvb3RUcmFuc3BvcnREZWNvcmF0b3IgZGlzYWxsb3dzIGNsb25l
KCcuLicpIikKICAgICAgICAgaWYgdHJhbnNwb3J0LmlzX3JlYWRvbmx5KCk6CiAgICAgICAgICAg
ICByZXR1cm4KICAgICAgICAgdHJhbnNwb3J0LnB1dF9ieXRlcygnZm9vJywgJ2JhcicpCgo=
=== modified file bzrlib/transport/__init__.py // encoding:base64
LS0tIGJ6cmxpYi90cmFuc3BvcnQvX19pbml0X18ucHkKKysrIGJ6cmxpYi90cmFuc3BvcnQvX19p
bml0X18ucHkKQEAgLTExNjQsNiArMTE2NCw4IEBACiByZWdpc3Rlcl9sYXp5X3RyYW5zcG9ydCgn
ZnRwOi8vJywgJ2J6cmxpYi50cmFuc3BvcnQuZnRwJywgJ0Z0cFRyYW5zcG9ydCcpCiByZWdpc3Rl
cl9sYXp5X3RyYW5zcG9ydCgnYWZ0cDovLycsICdienJsaWIudHJhbnNwb3J0LmZ0cCcsICdGdHBU
cmFuc3BvcnQnKQogcmVnaXN0ZXJfbGF6eV90cmFuc3BvcnQoJ21lbW9yeTovLycsICdienJsaWIu
dHJhbnNwb3J0Lm1lbW9yeScsICdNZW1vcnlUcmFuc3BvcnQnKQorcmVnaXN0ZXJfbGF6eV90cmFu
c3BvcnQoJ2Nocm9vdCsnLCAnYnpybGliLnRyYW5zcG9ydC5jaHJvb3QnLAorICAgICAgICAgICAg
ICAgICAgICAgICAgJ0Nocm9vdFRyYW5zcG9ydERlY29yYXRvcicpCiByZWdpc3Rlcl9sYXp5X3Ry
YW5zcG9ydCgncmVhZG9ubHkrJywgJ2J6cmxpYi50cmFuc3BvcnQucmVhZG9ubHknLCAnUmVhZG9u
bHlUcmFuc3BvcnREZWNvcmF0b3InKQogcmVnaXN0ZXJfbGF6eV90cmFuc3BvcnQoJ2Zha2VuZnMr
JywgJ2J6cmxpYi50cmFuc3BvcnQuZmFrZW5mcycsICdGYWtlTkZTVHJhbnNwb3J0RGVjb3JhdG9y
JykKIHJlZ2lzdGVyX2xhenlfdHJhbnNwb3J0KCd2ZmF0KycsCgo=
# revision id: andrew.bennetts at canonical.com-20061012060928-e387650ef98b70f5
# sha1: f2004de424458d7318345229f244e09f66defab5
# inventory sha1: d4d20ed79c50f03e799e6e46d7708a3c593271d1
# parent ids:
# pqm at pqm.ubuntu.com-20061010072307-037a6f63da8a1bdd
# properties:
# branch-nick: chroot decorator
More information about the bazaar
mailing list