diff --git a/borg/helpers.py b/borg/helpers.py index 72129f08e..2eae2ac1e 100644 --- a/borg/helpers.py +++ b/borg/helpers.py @@ -791,7 +791,7 @@ class Location: # regexes for misc. kinds of supported location specifiers: ssh_re = re.compile(r""" (?Pssh):// # ssh:// - (?:(?P[^@]+)@)? # user@ (optional) + (?:(?P[^@:/]+)@)? # user@ (optional) - username must not contain : or / (?P[^:/]+)(?::(?P\d+))? # host or host:port """ + path_re + optional_archive_re, re.VERBOSE) # path or path::archive @@ -802,7 +802,7 @@ class Location: # note: scp_re is also use for local pathes scp_re = re.compile(r""" ( - (?:(?P[^@]+)@)? # user@ (optional) + (?:(?P[^@:/]+)@)? # user@ (optional) - username must not contain : or / (?P[^:/]+): # host: (don't match / in host to disambiguate from file:) )? # user@host: part is optional """ + path_re + optional_archive_re, re.VERBOSE) # path with optional archive diff --git a/borg/testsuite/helpers.py b/borg/testsuite/helpers.py index d0fa86b6b..c6dadbece 100644 --- a/borg/testsuite/helpers.py +++ b/borg/testsuite/helpers.py @@ -94,6 +94,13 @@ class TestLocationWithoutEnv: assert repr(Location('/abs/path:with:colons')) == \ "Location(proto='file', user=None, host=None, port=None, path='/abs/path:with:colons', archive=None)" + def test_user_parsing(self): + # see issue #1930 + assert repr(Location('host:path::2016-12-31@23:59:59')) == \ + "Location(proto='ssh', user=None, host='host', port=None, path='path', archive='2016-12-31@23:59:59')" + assert repr(Location('ssh://host/path::2016-12-31@23:59:59')) == \ + "Location(proto='ssh', user=None, host='host', port=None, path='/path', archive='2016-12-31@23:59:59')" + def test_underspecified(self, monkeypatch): monkeypatch.delenv('BORG_REPO', raising=False) with pytest.raises(ValueError):