crash if a socket is listed with --files-from
Summary
If the files to backup as read from a file using the --files-from option (see #151 (closed)) lists a file which is actually a unix domain socket duplicity will crash with TypeError and the message: Can't mix strings and bytes in path components.
The crash only occurs when using --files-from.
Environment
Gentoo Linux
duplicity 0.8.23, patched with !120 (closed) and !125 (closed) - not ideal for bug reports sorry, but 0.8.23 was the stable gentoo package at the time
Steps to reproduce
Bind a unix domain socket to the filesystem to be backed up, name it in a text file, pass file to duplicity using --files-from. **boom**
What is the current bug behaviour?
Crash in Selection.Iterate.error_handler()
when calling os.path.join()
, reporting the above TypeError. If the --files-from option is not used, duplicity just skips the socket and emits a message in the log (correct behaviour).
What is the expected correct behaviour?
Same behaviour as observed without --files-from option.
Relevant logs and/or screenshots
ERROR 30 TypeError
. Traceback (innermost last):
. File "/usr/lib/python-exec/python3.10/duplicity", line 87, in <module>
. with_tempdir(main)
. File "/usr/lib/python-exec/python3.10/duplicity", line 70, in with_tempdir
. fn()
. File "/usr/lib/python3.10/site-packages/duplicity/dup_main.py", line 1580, in main
. do_backup(action)
. File "/usr/lib/python3.10/site-packages/duplicity/dup_main.py", line 1709, in do_backup
. full_backup(col_stats)
. File "/usr/lib/python3.10/site-packages/duplicity/dup_main.py", line 589, in full_backup
. bytes_written = write_multivol(u"full", tarblock_iter,
. File "/usr/lib/python3.10/site-packages/duplicity/dup_main.py", line 450, in write_multivol
. at_end = gpg.GzipWriteFile(tarblock_iter, tdp.name, config.volsize)
. File "/usr/lib/python3.10/site-packages/duplicity/gpg.py", line 451, in GzipWriteFile
. new_block = next(block_iter)
. File "/usr/lib/python3.10/site-packages/duplicity/diffdir.py", line 544, in __next__
. result = self.process(next(self.input_iter)) # pylint: disable=assignment-from-no-return
. File "/usr/lib/python3.10/site-packages/duplicity/diffdir.py", line 209, in get_delta_iter
. for new_path, sig_path in collated:
. File "/usr/lib/python3.10/site-packages/duplicity/diffdir.py", line 310, in collate2iters
. for relem1 in riter1:
. File "/usr/lib/python3.10/site-packages/duplicity/selection.py", line 93, in __next__
. return next(self.iter)
. File "/usr/lib/python3.10/site-packages/duplicity/selection.py", line 191, in Iterate
. subpath, scan = next(dirs_to_scan[-1])
. File "/usr/lib/python3.10/site-packages/duplicity/selection.py", line 155, in dir_scanner
. new_path = robust.check_common_error(
. File "/usr/lib/python3.10/site-packages/duplicity/robust.py", line 55, in check_common_error
. return error_handler(exc, *args)
. File "/usr/lib/python3.10/site-packages/duplicity/selection.py", line 113, in error_handler
. fullpath = os.path.join(path.name, filename)
. File "/usr/lib/python3.10/posixpath.py", line 90, in join
. genericpath._check_arg_types('join', a, *p)
. File "/usr/lib/python3.10/genericpath.py", line 155, in _check_arg_types
. raise TypeError("Can't mix strings and bytes in path components") from None
. TypeError: Can't mix strings and bytes in path components
Possible fixes
Duplicity crashes because the base path from the Path
instance for the socket location is a bytestring (Path.name
for the directory containing the socket) while the socket filename is a string (from the --files-from data structures). That the latter are strings otherwise works fine - when passed to Path.append()
the constructor for that class helpfully encodes them as bytes.
The data structures used to implement the --files-from option should probably store encoded byte sequences instead of str
instances, as this appears to be how the Path
class deals with them.
Will post a patch shortly.