Commit b1528d15 authored by bescoto's avatar bescoto

Fixed Popple's symlink bug which threatened source directory


git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup@578 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109
parent 9723e205
......@@ -11,6 +11,12 @@ was a timezone bug. (Thanks to Stephen Isard)
Fixed timezone bug. Hopefully this is the last one. (Thanks to
Randall Nortman for bug report.)
************** Serious bug fix ******************
If a directory in the source directory was replaced by certain
symlinks, then if later backups failed they could cause files in the
directory that the symlink pointed to to be deleted! Much thanks to
Alistair Popple for pointing this bug out and providing a test case.
New in v0.12.7 (2004/05/31)
---------------------------
......
......@@ -510,7 +510,7 @@ as data loss may result.\n""" % (self.mirror_rp.get_indexpath(),), 2)
inc_list = []
else: inc_rp, inc_list = inc_pair
if not mirror_rp:
mirror_rp = self.mirror_rp.new_index(inc_rp.index)
mirror_rp = self.mirror_rp.new_index_empty(inc_rp.index)
yield self.__class__(mirror_rp, inc_rp, inc_list)
def yield_mirrorrps(self, mirrorrp):
......
......@@ -790,6 +790,10 @@ class RPath(RORPath):
"""Return similar RPath but with new index"""
return self.__class__(self.conn, self.base, index)
def new_index_empty(self, index):
"""Return similar RPath with given index, but initialize to empty"""
return self.__class__(self.conn, self.base, index, {'type': None})
def open(self, mode, compress = None):
"""Return open file. Supports modes "w" and "r".
......
......@@ -596,5 +596,53 @@ class FinalMisc(PathSetter):
for inc in self.get_all_increments(rbdir):
assert inc.getinctime() >= 20000
class FinalBugs(PathSetter):
"""Test for specific bugs that have been reported"""
def test_symlink_popple(self):
"""Test for Popple's symlink bug
Earlier, certain symlinks could cause data loss in _source_
directory when regressing. See mailing lists around 4/2/05
for more info.
"""
self.delete_tmpdirs()
self.set_connections(None, None, None, None)
# Make directories
rp1 = rpath.RPath(Globals.local_connection, 'testfiles/sym_in1')
if rp1.lstat(): rp1.delete()
rp1.mkdir()
rp1_d = rp1.append('subdir')
rp1_d.mkdir()
rp1_d_f = rp1_d.append('file')
rp1_d_f.touch()
rp2 = rpath.RPath(Globals.local_connection, 'testfiles/sym_in2')
if rp2.lstat(): rp2.delete()
rp2.mkdir()
rp2_s = rp2.append('subdir')
rp2_s.symlink("%s/%s" % (os.getcwd(), rp1_d.path))
# Backup
self.exec_rb(10000, rp1.path, 'testfiles/output')
self.exec_rb(20000, rp2.path, 'testfiles/output')
# Make failed backup
rbdir = rpath.RPath(Globals.local_connection,
'testfiles/output/rdiff-backup-data')
curmir = rbdir.append('current_mirror.%s.data' %
(Time.timetostring(30000),))
curmir.touch()
# Regress
self.exec_rb_extra_args(30000, '--check-destination-dir',
'testfiles/output')
# Check to see if file still there
rp1_d_f.setdata()
assert rp1_d_f.isreg(), 'File %s corrupted' % (rp1_d_f.path,)
if __name__ == "__main__": unittest.main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment