|
@@ -23,7 +23,7 @@ from .helpers import sysinfo
|
|
|
from .helpers import bin_to_hex
|
|
|
from .helpers import replace_placeholders
|
|
|
from .helpers import yes
|
|
|
-from .repository import Repository
|
|
|
+from .repository import Repository, MAX_OBJECT_SIZE, LIST_SCAN_LIMIT
|
|
|
from .version import parse_version, format_version
|
|
|
from .logger import create_logger
|
|
|
|
|
@@ -57,6 +57,27 @@ def os_write(fd, data):
|
|
|
return amount
|
|
|
|
|
|
|
|
|
+def get_limited_unpacker(kind):
|
|
|
+ """return a limited Unpacker because we should not trust msgpack data received from remote"""
|
|
|
+ args = dict(use_list=False, # return tuples, not lists
|
|
|
+ max_bin_len=0, # not used
|
|
|
+ max_ext_len=0, # not used
|
|
|
+ max_buffer_size=3 * max(BUFSIZE, MAX_OBJECT_SIZE),
|
|
|
+ max_str_len=MAX_OBJECT_SIZE, # a chunk or other repo object
|
|
|
+ )
|
|
|
+ if kind == 'server':
|
|
|
+ args.update(dict(max_array_len=100, # misc. cmd tuples
|
|
|
+ max_map_len=100, # misc. cmd dicts
|
|
|
+ ))
|
|
|
+ elif kind == 'client':
|
|
|
+ args.update(dict(max_array_len=LIST_SCAN_LIMIT, # result list from repo.list() / .scan()
|
|
|
+ max_map_len=100, # misc. result dicts
|
|
|
+ ))
|
|
|
+ else:
|
|
|
+ raise ValueError('kind must be "server" or "client"')
|
|
|
+ return msgpack.Unpacker(**args)
|
|
|
+
|
|
|
+
|
|
|
class ConnectionClosed(Error):
|
|
|
"""Connection closed by remote host"""
|
|
|
|
|
@@ -185,7 +206,7 @@ class RepositoryServer: # pragma: no cover
|
|
|
# Make stderr blocking
|
|
|
fl = fcntl.fcntl(stderr_fd, fcntl.F_GETFL)
|
|
|
fcntl.fcntl(stderr_fd, fcntl.F_SETFL, fl & ~os.O_NONBLOCK)
|
|
|
- unpacker = msgpack.Unpacker(use_list=False)
|
|
|
+ unpacker = get_limited_unpacker('server')
|
|
|
while True:
|
|
|
r, w, es = select.select([stdin_fd], [], [], 10)
|
|
|
if r:
|
|
@@ -487,8 +508,7 @@ class RemoteRepository:
|
|
|
self.ignore_responses = set()
|
|
|
self.responses = {}
|
|
|
self.ratelimit = SleepingBandwidthLimiter(args.remote_ratelimit * 1024 if args and args.remote_ratelimit else 0)
|
|
|
-
|
|
|
- self.unpacker = msgpack.Unpacker(use_list=False)
|
|
|
+ self.unpacker = get_limited_unpacker('client')
|
|
|
self.server_version = parse_version('1.0.8') # fallback version if server is too old to send version information
|
|
|
self.p = None
|
|
|
testing = location.host == '__testsuite__'
|