1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2024-12-25 09:19:31 +00:00

Merge pull request #211 from ThomasWaldmann/archivename_validation

archive names with slashes are invalid, attic issue #180
This commit is contained in:
TW 2015-09-19 16:32:03 +02:00
commit 44d1a32e60
3 changed files with 17 additions and 5 deletions

View file

@ -718,7 +718,7 @@ def run(self, args=None):
help='do not create a backup archive') help='do not create a backup archive')
subparser.add_argument('archive', metavar='ARCHIVE', subparser.add_argument('archive', metavar='ARCHIVE',
type=location_validator(archive=True), 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, subparser.add_argument('paths', metavar='PATH', nargs='+', type=str,
help='paths to archive') help='paths to archive')

View file

@ -490,18 +490,20 @@ class Location:
"""Object representing a repository / archive location """Object representing a repository / archive location
""" """
proto = user = host = port = path = archive = None 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'(?P<proto>ssh)://(?:(?P<user>[^@]+)@)?' ssh_re = re.compile(r'(?P<proto>ssh)://(?:(?P<user>[^@]+)@)?'
r'(?P<host>[^:/#]+)(?::(?P<port>\d+))?' r'(?P<host>[^:/#]+)(?::(?P<port>\d+))?'
r'(?P<path>[^:]+)(?:::(?P<archive>.+))?$') r'(?P<path>[^:]+)(?:::(?P<archive>[^/]+))?$')
file_re = re.compile(r'(?P<proto>file)://' file_re = re.compile(r'(?P<proto>file)://'
r'(?P<path>[^:]+)(?:::(?P<archive>.+))?$') r'(?P<path>[^:]+)(?:::(?P<archive>[^/]+))?$')
scp_re = re.compile(r'((?:(?P<user>[^@]+)@)?(?P<host>[^:/]+):)?' scp_re = re.compile(r'((?:(?P<user>[^@]+)@)?(?P<host>[^:/]+):)?'
r'(?P<path>[^:]+)(?:::(?P<archive>.+))?$') r'(?P<path>[^:]+)(?:::(?P<archive>[^/]+))?$')
# get the repo from BORG_RE env and the optional archive from param. # get the repo from BORG_RE env and the optional archive from param.
# if the syntax requires giving REPOSITORY (see "borg mount"), # if the syntax requires giving REPOSITORY (see "borg mount"),
# use "::" to let it use the env var. # use "::" to let it use the env var.
# if REPOSITORY argument is optional, it'll automatically use the env. # if REPOSITORY argument is optional, it'll automatically use the env.
env_re = re.compile(r'(?:::(?P<archive>.+)?)?$') env_re = re.compile(r'(?:::(?P<archive>[^/]+)?)?$')
def __init__(self, text=''): def __init__(self, text=''):
self.orig = text self.orig = text

View file

@ -81,6 +81,11 @@ def test_no_double_colon(self, monkeypatch):
with pytest.raises(ValueError): with pytest.raises(ValueError):
Location('ssh://localhost:22/path:archive') 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): def test_canonical_path(self, monkeypatch):
monkeypatch.delenv('BORG_REPO', raising=False) monkeypatch.delenv('BORG_REPO', raising=False)
locations = ['some/path::archive', 'file://some/path::archive', 'host:some/path::archive', locations = ['some/path::archive', 'file://some/path::archive', 'host:some/path::archive',
@ -134,6 +139,11 @@ def test_relpath(self, monkeypatch):
assert repr(Location()) == \ assert repr(Location()) == \
"Location(proto='file', user=None, host=None, port=None, path='some/relative/path', archive=None)" "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): class FormatTimedeltaTestCase(BaseTestCase):