# HG changeset patch # User RhodeCode Admin # Date 2024-03-03 07:40:12 # Node ID 545f93332fe36e889cccf3fb5b6b27a9a595fd30 # Parent 90d0c6c09a0caf2ff459e738e914e9f55067ef72 fix(svn): more binary protocol svn ssh fixes diff --git a/rhodecode/apps/ssh_support/lib/backends/svn.py b/rhodecode/apps/ssh_support/lib/backends/svn.py --- a/rhodecode/apps/ssh_support/lib/backends/svn.py +++ b/rhodecode/apps/ssh_support/lib/backends/svn.py @@ -25,7 +25,6 @@ import tempfile from subprocess import Popen, PIPE import urllib.parse -from rhodecode.lib.str_utils import safe_bytes from rhodecode_tools.lib.utils import safe_str from .base import SshVcsServer @@ -103,19 +102,27 @@ class SubversionTunnelWrapper(object): def patch_first_client_response(self, response, **kwargs): self.create_hooks_env() - data = response.copy() - data.update(kwargs) - data['url'] = self._svn_string(data['url']) - data['ra_client'] = self._svn_string(data['ra_client']) - data['client'] = data['client'] or '' - buffer_ = safe_bytes( - "( {version} ( {capabilities} ) {url}{ra_client}" - "( {client}) ) ".format(**data)) + + version = response['version'] + capabilities = response['capabilities'] + client = response['client'] or b'' + + url = self._svn_bytes(response['url']) + ra_client = self._svn_bytes(response['ra_client']) + + buffer_ = b"( %b ( %b ) %b%b( %b) ) " % ( + version, + capabilities, + url, + ra_client, + client + ) self.process.stdin.write(buffer_) def fail(self, message): - print("( failure ( ( 210005 {message} 0: 0 ) ) )".format( - message=self._svn_string(message))) + fail_msg = b"( failure ( ( 210005 %b 0: 0 ) ) )" % self._svn_bytes(message) + sys.stdout.buffer.write(fail_msg) + sys.stdout.flush() self.remove_configs() self.process.kill() return 1 @@ -123,10 +130,11 @@ class SubversionTunnelWrapper(object): def interrupt(self, signum, frame): self.fail("Exited by timeout") - def _svn_string(self, str_): - if not str_: - return '' - return f'{len(str_)}:{str_} ' + def _svn_bytes(self, bytes_: bytes) -> bytes: + if not bytes_: + return b'' + + return f'{len(bytes_)}:'.encode() + bytes_ + b' ' def _read_first_client_response(self): buffer_ = b""