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) ...@@ -11,6 +11,12 @@ was a timezone bug. (Thanks to Stephen Isard)
Fixed timezone bug. Hopefully this is the last one. (Thanks to Fixed timezone bug. Hopefully this is the last one. (Thanks to
Randall Nortman for bug report.) 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) New in v0.12.7 (2004/05/31)
--------------------------- ---------------------------
......
...@@ -510,7 +510,7 @@ as data loss may result.\n""" % (self.mirror_rp.get_indexpath(),), 2) ...@@ -510,7 +510,7 @@ as data loss may result.\n""" % (self.mirror_rp.get_indexpath(),), 2)
inc_list = [] inc_list = []
else: inc_rp, inc_list = inc_pair else: inc_rp, inc_list = inc_pair
if not mirror_rp: 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) yield self.__class__(mirror_rp, inc_rp, inc_list)
def yield_mirrorrps(self, mirrorrp): def yield_mirrorrps(self, mirrorrp):
......
...@@ -790,6 +790,10 @@ class RPath(RORPath): ...@@ -790,6 +790,10 @@ class RPath(RORPath):
"""Return similar RPath but with new index""" """Return similar RPath but with new index"""
return self.__class__(self.conn, self.base, 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): def open(self, mode, compress = None):
"""Return open file. Supports modes "w" and "r". """Return open file. Supports modes "w" and "r".
......
...@@ -597,4 +597,52 @@ class FinalMisc(PathSetter): ...@@ -597,4 +597,52 @@ class FinalMisc(PathSetter):
assert inc.getinctime() >= 20000 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() 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