From 2910d130553ecf56e988901bac0eddfb8ad87d25 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Tue, 8 Jan 2019 14:39:28 +0100 Subject: [PATCH] use try/finally to ensure correct memoryview release see #4243. --- src/borg/repository.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/borg/repository.py b/src/borg/repository.py index e04c0b8cb..eedeba1ae 100644 --- a/src/borg/repository.py +++ b/src/borg/repository.py @@ -1395,18 +1395,22 @@ class LoggedIO: with open(backup_filename, 'rb') as backup_fd: # note: file must not be 0 size (windows can't create 0 size mapping) with mmap.mmap(backup_fd.fileno(), 0, access=mmap.ACCESS_READ) as mm: - with memoryview(mm) as data, open(filename, 'wb') as fd: - fd.write(MAGIC) - while len(data) >= self.header_fmt.size: - crc, size, tag = self.header_fmt.unpack(data[:self.header_fmt.size]) - if size < self.header_fmt.size or size > len(data): - data = data[1:] - continue - if crc32(data[4:size]) & 0xffffffff != crc: - data = data[1:] - continue - fd.write(data[:size]) - data = data[size:] + data = memoryview(mm) # didn't use memoryview context manager, it does not work correctly. + try: + with open(filename, 'wb') as fd: + fd.write(MAGIC) + while len(data) >= self.header_fmt.size: + crc, size, tag = self.header_fmt.unpack(data[:self.header_fmt.size]) + if size < self.header_fmt.size or size > len(data): + data = data[1:] + continue + if crc32(data[4:size]) & 0xffffffff != crc: + data = data[1:] + continue + fd.write(data[:size]) + data = data[size:] + finally: + data.release() def read(self, segment, offset, id, read_data=True): """