fix(svn-ssh): fixed svn ssh wrapper

This commit is contained in:
RhodeCode Admin 2024-03-01 13:40:11 +01:00
parent f56c72e441
commit 747534f76d

View file

@ -25,6 +25,8 @@ 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
log = logging.getLogger(__name__)
@ -81,7 +83,7 @@ class SubversionTunnelWrapper(object):
def sync(self):
while self.process.poll() is None:
next_byte = self.stdin.read(1)
next_byte = self.stdin.buffer.read(1)
if not next_byte:
break
self.process.stdin.write(next_byte)
@ -106,7 +108,7 @@ class SubversionTunnelWrapper(object):
data['url'] = self._svn_string(data['url'])
data['ra_client'] = self._svn_string(data['ra_client'])
data['client'] = data['client'] or ''
buffer_ = (
buffer_ = safe_bytes(
"( {version} ( {capabilities} ) {url}{ra_client}"
"( {client}) ) ".format(**data))
self.process.stdin.write(buffer_)
@ -127,21 +129,21 @@ class SubversionTunnelWrapper(object):
return f'{len(str_)}:{str_} '
def _read_first_client_response(self):
buffer_ = ""
buffer_ = b""
brackets_stack = []
while True:
next_byte = self.stdin.read(1)
next_byte = self.stdin.buffer.read(1)
buffer_ += next_byte
if next_byte == "(":
if next_byte == b"(":
brackets_stack.append(next_byte)
elif next_byte == ")":
elif next_byte == b")":
brackets_stack.pop()
elif next_byte == " " and not brackets_stack:
elif next_byte == b" " and not brackets_stack:
break
return buffer_
def _parse_first_client_response(self, buffer_):
def _parse_first_client_response(self, buffer_: bytes):
"""
According to the Subversion RA protocol, the first request
should look like:
@ -151,16 +153,20 @@ class SubversionTunnelWrapper(object):
Please check https://svn.apache.org/repos/asf/subversion/trunk/subversion/libsvn_ra_svn/protocol
"""
version_re = r'(?P<version>\d+)'
capabilities_re = r'\(\s(?P<capabilities>[\w\d\-\ ]+)\s\)'
url_re = r'\d+\:(?P<url>[\W\w]+)'
ra_client_re = r'(\d+\:(?P<ra_client>[\W\w]+)\s)'
client_re = r'(\d+\:(?P<client>[\W\w]+)\s)*'
version_re = br'(?P<version>\d+)'
capabilities_re = br'\(\s(?P<capabilities>[\w\d\-\ ]+)\s\)'
url_re = br'\d+\:(?P<url>[\W\w]+)'
ra_client_re = br'(\d+\:(?P<ra_client>[\W\w]+)\s)'
client_re = br'(\d+\:(?P<client>[\W\w]+)\s)*'
regex = re.compile(
r'^\(\s{version}\s{capabilities}\s{url}\s{ra_client}'
r'\(\s{client}\)\s\)\s*$'.format(
version=version_re, capabilities=capabilities_re,
url=url_re, ra_client=ra_client_re, client=client_re))
br'^\(\s%b\s%b\s%b\s%b'
br'\(\s%b\)\s\)\s*$' % (
version_re,
capabilities_re,
url_re,
ra_client_re,
client_re)
)
matcher = regex.match(buffer_)
return matcher.groupdict() if matcher else None
@ -202,7 +208,7 @@ class SubversionTunnelWrapper(object):
url_parts = urllib.parse.urlparse(first_response['url'])
self.server.repo_name = self._match_repo_name(url_parts.path.strip('/'))
self.server.repo_name = self._match_repo_name(safe_str(url_parts.path).strip('/'))
exit_code = self.server._check_permissions(action)
if exit_code: