Skip to content

Commit

Permalink
Fix selection of overlapping patterns (#197)
Browse files Browse the repository at this point in the history
- closes #137 (thanks to @ilario for the first steps)
- closes #22
- normally selection patterns not relative to the root path lead to an error,
  but 'selection' was accepted for 'select' because they start alike.
- test accordingly added to testing/selection.py
  • Loading branch information
ericzolf committed Dec 1, 2019
1 parent 6cbd5e4 commit 96e5b5a
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
22 changes: 14 additions & 8 deletions src/rdiff_backup/selection.py
Expand Up @@ -86,6 +86,7 @@ def __init__(self, rootrp):
self.selection_functions = []
self.rpath = rootrp
self.prefix = self.rpath.path
self.prefixindex = tuple([x for x in self.prefix.split(b"/") if x])

def set_iter(self, sel_func=None):
"""Initialize more variables, get ready to iterate
Expand Down Expand Up @@ -185,6 +186,17 @@ def Iterate(self, rp, rec_func, sel_func):
else:
assert 0, "Invalid selection result %s" % (str(s), )

def get_relative_index(self, filename):
"""return the index of a file relative to the current prefix
or fail if they're not relative to each other"""

fileindex = tuple([x for x in filename.split(b"/") if x])

# are the first elements of the path the same?
if fileindex[:len(self.prefixindex)] != self.prefixindex:
raise FilePrefixError(filename)
return fileindex[len(self.prefixindex):]

def listdir(self, dir_rp):
"""List directory rpath with error logging"""

Expand Down Expand Up @@ -420,10 +432,7 @@ def filelist_parse_line(self, line, include):
include = 0
line = line[2:]

if not line.startswith(self.prefix):
raise FilePrefixError(line)
line = line[len(self.prefix):] # Discard prefix
index = tuple([x for x in line.split(b"/") if x]) # remove empties
index = self.get_relative_index(line)
return (index, include)

def filelist_pair_match(self, rp, pair):
Expand Down Expand Up @@ -616,10 +625,7 @@ def glob_get_filename_sf(self, filename, include):
globbing characters are used.
"""
if not filename.startswith(self.prefix):
raise FilePrefixError(filename)
index = tuple(
[x for x in filename[len(self.prefix):].split(b"/") if x])
index = self.get_relative_index(filename)
return self.glob_get_tuple_sf(index, include)

def glob_get_tuple_sf(self, tuple, include):
Expand Down
8 changes: 8 additions & 0 deletions testing/selectiontest.py
Expand Up @@ -41,6 +41,10 @@ def testTupleInclude(self):
"""Test include selection function made from a regular filename"""
self.assertRaises(FilePrefixError, self.Select.glob_get_filename_sf,
b"foo", 1)
self.assertRaises(FilePrefixError, self.Select.glob_get_filename_sf,
b"rdiff-backup_testfiles/sel", 1)
self.assertRaises(FilePrefixError, self.Select.glob_get_filename_sf,
b"rdiff-backup_testfiles/selection", 1)

sf2 = self.Select.glob_get_sf(
"rdiff-backup_testfiles/select/usr/local/bin/", 1)
Expand All @@ -55,6 +59,10 @@ def testTupleExclude(self):
"""Test exclude selection function made from a regular filename"""
self.assertRaises(FilePrefixError, self.Select.glob_get_filename_sf,
b"foo", 0)
self.assertRaises(FilePrefixError, self.Select.glob_get_filename_sf,
b"rdiff-backup_testfiles/sel", 0)
self.assertRaises(FilePrefixError, self.Select.glob_get_filename_sf,
b"rdiff-backup_testfiles/selection", 0)

sf2 = self.Select.glob_get_sf(
"rdiff-backup_testfiles/select/usr/local/bin/", 0)
Expand Down

0 comments on commit 96e5b5a

Please sign in to comment.