From 903ef41dc011e27f101c12b49dfffc42076d472a Mon Sep 17 00:00:00 2001 From: JoeLametta Date: Thu, 18 Oct 2018 10:00:00 +0000 Subject: [PATCH] Limit length of filenames If whipper generated filenames are longer thant the maximum value supported by the filesystem, the I/O operations are going to fail. With this commit filenames which may be too long are truncated to the maximum allowable length. Fixes #197. --- whipper/common/common.py | 10 ++++++++++ whipper/common/program.py | 6 +++--- whipper/program/cdparanoia.py | 4 ++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/whipper/common/common.py b/whipper/common/common.py index c8aefd4e..5a38407e 100644 --- a/whipper/common/common.py +++ b/whipper/common/common.py @@ -152,6 +152,16 @@ class MissingFrames(Exception): """ pass +def truncate_filename(path): + """ + Truncate filename to the max. len. allowed by the path's filesystem + Should handle unicode correctly too + """ + p, f = os.path.split(os.path.normpath(path)) + f, e = os.path.splitext(f) + fn_lim = os.pathconf(p, 'PC_NAME_MAX') + length = fn_lim - len(e) + return os.path.join(p, f[:length] + e) def shrinkPath(path): """ diff --git a/whipper/common/program.py b/whipper/common/program.py index 5a1daaac..78790b40 100644 --- a/whipper/common/program.py +++ b/whipper/common/program.py @@ -574,7 +574,7 @@ def verifyImage(self, runner, table): return accurip.verify_result(self.result, responses, checksums) def write_m3u(self, discname): - m3uPath = u'%s.m3u' % discname + m3uPath = common.truncate_filename(discname + '.m3u') with open(m3uPath, 'w') as f: f.write(u'#EXTM3U\n'.encode('utf-8')) for track in self.result.tracks: @@ -596,7 +596,7 @@ def write_m3u(self, discname): def writeCue(self, discName): assert self.result.table.canCue() - cuePath = '%s.cue' % discName + cuePath = common.truncate_filename(discName + '.cue') logger.debug('write .cue file to %s', cuePath) handle = open(cuePath, 'w') # FIXME: do we always want utf-8 ? @@ -608,7 +608,7 @@ def writeCue(self, discName): return cuePath def writeLog(self, discName, logger): - logPath = '%s.log' % discName + logPath = common.truncate_filename(discName + '.log') handle = open(logPath, 'w') log = logger.log(self.result) handle.write(log.encode('utf-8')) diff --git a/whipper/program/cdparanoia.py b/whipper/program/cdparanoia.py index 3163dc7d..07f2e699 100644 --- a/whipper/program/cdparanoia.py +++ b/whipper/program/cdparanoia.py @@ -481,8 +481,8 @@ def __init__(self, path, table, start, stop, overread, offset=0, except IOError as e: if errno.ENAMETOOLONG != e.errno: raise - path = common.shrinkPath(path) - tmpoutpath = path + u'.part' + path = common.truncate_filename(common.shrinkPath(path)) + tmpoutpath = common.truncate_filename(path + u'.part') open(tmpoutpath, 'wb').close() self._tmppath = tmpoutpath self.path = path