diff --git a/src/calibre/db/backend.py b/src/calibre/db/backend.py index de976e24e9..b42537116d 100644 --- a/src/calibre/db/backend.py +++ b/src/calibre/db/backend.py @@ -47,6 +47,7 @@ Differences in semantics from pysqlite: ''' CUSTOM_DATA_TYPES = frozenset(['rating', 'text', 'comments', 'datetime', 'int', 'float', 'bool', 'series', 'composite', 'enumeration']) +WINDOWS_RESERVED_NAMES = frozenset('CON PRN AUX NUL COM1 COM2 COM3 COM4 COM5 COM6 COM7 COM8 COM9 LPT1 LPT2 LPT3 LPT4 LPT5 LPT6 LPT7 LPT8 LPT9'.split()) class DynamicFilter(object): # {{{ @@ -1139,6 +1140,8 @@ class DB(object): if not author: author = ascii_filename(_('Unknown')).decode( 'ascii', 'replace') + if author.upper() in WINDOWS_RESERVED_NAMES: + author += 'w' return '%s/%s%s' % (author, title, book_id) def construct_file_name(self, book_id, title, author, extlen): diff --git a/src/calibre/db/tests/filesystem.py b/src/calibre/db/tests/filesystem.py index f7fa341df1..2f90557bb3 100644 --- a/src/calibre/db/tests/filesystem.py +++ b/src/calibre/db/tests/filesystem.py @@ -132,6 +132,13 @@ class FilesystemTest(BaseTest): fpath = cache.format_abspath(1, cache.formats(1)[0]) self.assertLessEqual(len(fpath), len(cache.backend.library_path) + cache.backend.PATH_LIMIT * 4) + def test_reserved_names(self): + ' Test that folders are not created with a windows reserve name ' + cache = self.init_cache() + cache.set_field('authors', {1:'con'}) + p = cache.field_for('path', 1).replace(os.sep, '/').split('/') + self.assertNotIn('con', p) + def test_fname_change(self): ' Test the changing of the filename but not the folder name ' cache = self.init_cache()