From f24979bc096601d16ff69bd85eb74bee79129e42 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Sun, 3 Apr 2022 16:49:28 +0200 Subject: [PATCH 1/2] fix scp repo url parsing for ip v6 addrs, fixes #6526 added a negative lookahead/lookbehind to make sure an ipv6 addr (enclosed in square brackets) does not get badly matched by the regex part intended for hostnames and ipv4 addrs only. the other part of that regex which is actually intended to match ipv6 addrs only matches if they are enclosed in square brackets. also added tests for ssh and scp style repo URLs with ipv6 addrs in brackets. also: made regex more readable, putting these 2 cases on separate lines. --- src/borg/helpers/parseformat.py | 12 ++++++++---- src/borg/testsuite/helpers.py | 6 ++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/borg/helpers/parseformat.py b/src/borg/helpers/parseformat.py index f595c8d39..39be4a544 100644 --- a/src/borg/helpers/parseformat.py +++ b/src/borg/helpers/parseformat.py @@ -355,10 +355,14 @@ class Location: # note: scp_re is also use for local paths scp_re = re.compile(r""" ( - """ + optional_user_re + r""" # user@ (optional) - (?P([^:/]+|\[[0-9a-fA-F:.]+\])): # host: (don't match / or [ipv6] in host to disambiguate from file:) - )? # user@host: part is optional - """ + scp_path_re + optional_archive_re, re.VERBOSE) # path with optional archive + """ + optional_user_re + r""" # user@ (optional) + (?P( # host can be ipv6 addr in brackets or something else + (?!\[)[^:/]+(? Date: Sun, 3 Apr 2022 19:01:11 +0200 Subject: [PATCH 2/2] use same host regex for ssh and scp style, refactor/clean up although bug #6526 did not show with ssh style URLs, we should not have different regexes for the host part for ssh and scp style. thus i extracted the host_re from both and also cleaned up a bit. --- src/borg/helpers/parseformat.py | 35 +++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/borg/helpers/parseformat.py b/src/borg/helpers/parseformat.py index 39be4a544..08ec8df8e 100644 --- a/src/borg/helpers/parseformat.py +++ b/src/borg/helpers/parseformat.py @@ -341,28 +341,33 @@ class Location: (?P[^/]+) # archive name must not contain "/" )?$""" # must match until the end + # host NAME, or host IP ADDRESS (v4 or v6, v6 must be in square brackets) + host_re = r""" + (?P( + (?!\[)[^:/]+(?ssh):// # ssh:// - """ + optional_user_re + r""" # user@ (optional) - (?P([^:/]+|\[[0-9a-fA-F:.]+\]))(?::(?P\d+))? # host or host:port or [ipv6] or [ipv6]:port - """ + abs_path_re + optional_archive_re, re.VERBOSE) # path or path::archive + (?Pssh):// # ssh:// + """ + optional_user_re + host_re + r""" # user@ (optional), host name or address + (?::(?P\d+))? # :port (optional) + """ + abs_path_re + optional_archive_re, re.VERBOSE) # path or path::archive file_re = re.compile(r""" - (?Pfile):// # file:// - """ + file_path_re + optional_archive_re, re.VERBOSE) # servername/path, path or path::archive + (?Pfile):// # file:// + """ + file_path_re + optional_archive_re, re.VERBOSE) # servername/path, path or path::archive - # note: scp_re is also use for local paths + # note: scp_re is also used for local paths scp_re = re.compile(r""" ( - """ + optional_user_re + r""" # user@ (optional) - (?P( # host can be ipv6 addr in brackets or something else - (?!\[)[^:/]+(?