From cad0515178f999467d7d9169cf47eb845ebd59f2 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Sat, 19 Sep 2015 16:09:20 +0200 Subject: [PATCH] archive names with slashes are invalid, attic issue #180 for borg mount's FUSE filesystem, we use the archive name as a directory name, thus slashes are not allowed. --- borg/archiver.py | 2 +- borg/helpers.py | 10 ++++++---- borg/testsuite/helpers.py | 10 ++++++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/borg/archiver.py b/borg/archiver.py index 465fcc85d..a6b5acdd4 100644 --- a/borg/archiver.py +++ b/borg/archiver.py @@ -718,7 +718,7 @@ def run(self, args=None): help='do not create a backup archive') subparser.add_argument('archive', metavar='ARCHIVE', type=location_validator(archive=True), - help='archive to create') + help='name of archive to create (must be also a valid directory name)') subparser.add_argument('paths', metavar='PATH', nargs='+', type=str, help='paths to archive') diff --git a/borg/helpers.py b/borg/helpers.py index 45d200a48..9dab70aa8 100644 --- a/borg/helpers.py +++ b/borg/helpers.py @@ -490,18 +490,20 @@ class Location: """Object representing a repository / archive location """ proto = user = host = port = path = archive = None + # borg mount's FUSE filesystem creates one level of directories from + # the archive names. Thus, we must not accept "/" in archive names. ssh_re = re.compile(r'(?Pssh)://(?:(?P[^@]+)@)?' r'(?P[^:/#]+)(?::(?P\d+))?' - r'(?P[^:]+)(?:::(?P.+))?$') + r'(?P[^:]+)(?:::(?P[^/]+))?$') file_re = re.compile(r'(?Pfile)://' - r'(?P[^:]+)(?:::(?P.+))?$') + r'(?P[^:]+)(?:::(?P[^/]+))?$') scp_re = re.compile(r'((?:(?P[^@]+)@)?(?P[^:/]+):)?' - r'(?P[^:]+)(?:::(?P.+))?$') + r'(?P[^:]+)(?:::(?P[^/]+))?$') # get the repo from BORG_RE env and the optional archive from param. # if the syntax requires giving REPOSITORY (see "borg mount"), # use "::" to let it use the env var. # if REPOSITORY argument is optional, it'll automatically use the env. - env_re = re.compile(r'(?:::(?P.+)?)?$') + env_re = re.compile(r'(?:::(?P[^/]+)?)?$') def __init__(self, text=''): self.orig = text diff --git a/borg/testsuite/helpers.py b/borg/testsuite/helpers.py index f755df22a..25ec48c90 100644 --- a/borg/testsuite/helpers.py +++ b/borg/testsuite/helpers.py @@ -81,6 +81,11 @@ def test_no_double_colon(self, monkeypatch): with pytest.raises(ValueError): Location('ssh://localhost:22/path:archive') + def test_no_slashes(self, monkeypatch): + monkeypatch.delenv('BORG_REPO', raising=False) + with pytest.raises(ValueError): + Location('/some/path/to/repo::archive_name_with/slashes/is_invalid') + def test_canonical_path(self, monkeypatch): monkeypatch.delenv('BORG_REPO', raising=False) locations = ['some/path::archive', 'file://some/path::archive', 'host:some/path::archive', @@ -134,6 +139,11 @@ def test_relpath(self, monkeypatch): assert repr(Location()) == \ "Location(proto='file', user=None, host=None, port=None, path='some/relative/path', archive=None)" + def test_no_slashes(self, monkeypatch): + monkeypatch.setenv('BORG_REPO', '/some/absolute/path') + with pytest.raises(ValueError): + Location('::archive_name_with/slashes/is_invalid') + class FormatTimedeltaTestCase(BaseTestCase):