From 335d599db4f812b3ad6a87bb3a2b31a6c9a772a9 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Fri, 9 Dec 2016 03:37:13 +0100 Subject: [PATCH] fix location parser for archives with @ char, add test, fixes #1930 we must exclude colon and slash chars from the username, otherwise the term for the user part will match everything up to a @ char in the archive name. a slash can't be in a username as the home directory would contain a illegal slash (slash is path sep), a colon likely also should not be in a username because chown user:group ... syntax. --- borg/helpers.py | 4 ++-- borg/testsuite/helpers.py | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) 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):