Browse Source

use safe_encode/decode

Thomas Waldmann 9 years ago
parent
commit
d883791df7
2 changed files with 8 additions and 8 deletions
  1. 6 6
      borg/archive.py
  2. 2 2
      borg/archiver.py

+ 6 - 6
borg/archive.py

@@ -18,7 +18,7 @@ from . import xattr
 from .compress import Compressor, COMPR_BUFFER
 from .compress import Compressor, COMPR_BUFFER
 from .constants import *  # NOQA
 from .constants import *  # NOQA
 from .helpers import Chunk, Error, uid2user, user2uid, gid2group, group2gid, \
 from .helpers import Chunk, Error, uid2user, user2uid, gid2group, group2gid, \
-    parse_timestamp, to_localtime, format_time, format_timedelta, \
+    parse_timestamp, to_localtime, format_time, format_timedelta, safe_encode, safe_decode, \
     Manifest, Statistics, decode_dict, make_path_safe, StableDict, int_to_bigint, bigint_to_int, bin_to_hex, \
     Manifest, Statistics, decode_dict, make_path_safe, StableDict, int_to_bigint, bigint_to_int, bin_to_hex, \
     ProgressIndicatorPercent, ChunkIteratorFileWrapper, remove_surrogates, log_multi, \
     ProgressIndicatorPercent, ChunkIteratorFileWrapper, remove_surrogates, log_multi, \
     PathPrefixPattern, FnmatchPattern, open_item, file_status, format_file_size, consume
     PathPrefixPattern, FnmatchPattern, open_item, file_status, format_file_size, consume
@@ -175,7 +175,7 @@ class Archive:
         self.id = id
         self.id = id
         self.metadata = self._load_meta(self.id)
         self.metadata = self._load_meta(self.id)
         decode_dict(self.metadata, ARCHIVE_TEXT_KEYS)
         decode_dict(self.metadata, ARCHIVE_TEXT_KEYS)
-        self.metadata[b'cmdline'] = [arg.decode('utf-8', 'surrogateescape') for arg in self.metadata[b'cmdline']]
+        self.metadata[b'cmdline'] = [safe_decode(arg) for arg in self.metadata[b'cmdline']]
         self.name = self.metadata[b'name']
         self.name = self.metadata[b'name']
 
 
     @property
     @property
@@ -566,7 +566,7 @@ Number of files: {0.stats.nfiles}'''.format(
                 return status
                 return status
             else:
             else:
                 self.hard_links[st.st_ino, st.st_dev] = safe_path
                 self.hard_links[st.st_ino, st.st_dev] = safe_path
-        path_hash = self.key.id_hash(os.path.join(self.cwd, path).encode('utf-8', 'surrogateescape'))
+        path_hash = self.key.id_hash(safe_encode(os.path.join(self.cwd, path)))
         first_run = not cache.files
         first_run = not cache.files
         ids = cache.file_known_and_unchanged(path_hash, st, ignore_inode)
         ids = cache.file_known_and_unchanged(path_hash, st, ignore_inode)
         if first_run:
         if first_run:
@@ -794,7 +794,7 @@ class ArchiveChecker:
             for chunk_id, size, csize in item[b'chunks']:
             for chunk_id, size, csize in item[b'chunks']:
                 if chunk_id not in self.chunks:
                 if chunk_id not in self.chunks:
                     # If a file chunk is missing, create an all empty replacement chunk
                     # If a file chunk is missing, create an all empty replacement chunk
-                    logger.error('{}: Missing file chunk detected (Byte {}-{})'.format(item[b'path'].decode('utf-8', 'surrogateescape'), offset, offset + size))
+                    logger.error('{}: Missing file chunk detected (Byte {}-{})'.format(safe_decode(item[b'path']), offset, offset + size))
                     self.error_found = True
                     self.error_found = True
                     data = bytes(size)
                     data = bytes(size)
                     chunk_id = self.key.id_hash(data)
                     chunk_id = self.key.id_hash(data)
@@ -881,7 +881,7 @@ class ArchiveChecker:
                 if archive[b'version'] != 1:
                 if archive[b'version'] != 1:
                     raise Exception('Unknown archive metadata version')
                     raise Exception('Unknown archive metadata version')
                 decode_dict(archive, ARCHIVE_TEXT_KEYS)
                 decode_dict(archive, ARCHIVE_TEXT_KEYS)
-                archive[b'cmdline'] = [arg.decode('utf-8', 'surrogateescape') for arg in archive[b'cmdline']]
+                archive[b'cmdline'] = [safe_decode(arg) for arg in archive[b'cmdline']]
                 items_buffer = ChunkBuffer(self.key)
                 items_buffer = ChunkBuffer(self.key)
                 items_buffer.write_chunk = add_callback
                 items_buffer.write_chunk = add_callback
                 for item in robust_iterator(archive):
                 for item in robust_iterator(archive):
@@ -1186,7 +1186,7 @@ class ArchiveRecreater:
         logger.info('Found %s, will resume interrupted operation', target_name)
         logger.info('Found %s, will resume interrupted operation', target_name)
         old_target = self.open_archive(target_name)
         old_target = self.open_archive(target_name)
         resume_id = old_target.metadata[b'recreate_source_id']
         resume_id = old_target.metadata[b'recreate_source_id']
-        resume_args = [arg.decode('utf-8', 'surrogateescape') for arg in old_target.metadata[b'recreate_args']]
+        resume_args = [safe_decode(arg) for arg in old_target.metadata[b'recreate_args']]
         if resume_id != archive.id:
         if resume_id != archive.id:
             logger.warning('Source archive changed, will discard %s and start over', target_name)
             logger.warning('Source archive changed, will discard %s and start over', target_name)
             logger.warning('Saved fingerprint:   %s', bin_to_hex(resume_id))
             logger.warning('Saved fingerprint:   %s', bin_to_hex(resume_id))

+ 2 - 2
borg/archiver.py

@@ -19,7 +19,7 @@ import traceback
 from . import __version__
 from . import __version__
 from .helpers import Error, location_validator, archivename_validator, format_time, format_file_size, \
 from .helpers import Error, location_validator, archivename_validator, format_time, format_file_size, \
     parse_pattern, PathPrefixPattern, to_localtime, timestamp, \
     parse_pattern, PathPrefixPattern, to_localtime, timestamp, \
-    get_cache_dir, prune_within, prune_split, bin_to_hex, \
+    get_cache_dir, prune_within, prune_split, bin_to_hex, safe_encode, \
     Manifest, remove_surrogates, update_excludes, format_archive, check_extension_modules, Statistics, \
     Manifest, remove_surrogates, update_excludes, format_archive, check_extension_modules, Statistics, \
     dir_is_tagged, ChunkerParams, CompressionSpec, is_slow_msgpack, yes, sysinfo, \
     dir_is_tagged, ChunkerParams, CompressionSpec, is_slow_msgpack, yes, sysinfo, \
     log_multi, PatternMatcher, ItemFormatter
     log_multi, PatternMatcher, ItemFormatter
@@ -739,7 +739,7 @@ class Archiver:
                 else:
                 else:
                     write = sys.stdout.buffer.write
                     write = sys.stdout.buffer.write
                 for item in archive.iter_items(lambda item: matcher.match(item[b'path'])):
                 for item in archive.iter_items(lambda item: matcher.match(item[b'path'])):
-                    write(formatter.format_item(item).encode('utf-8', errors='surrogateescape'))
+                    write(safe_encode(formatter.format_item(item)))
         else:
         else:
             for archive_info in manifest.list_archive_infos(sort_by='ts'):
             for archive_info in manifest.list_archive_infos(sort_by='ts'):
                 if args.prefix and not archive_info.name.startswith(args.prefix):
                 if args.prefix and not archive_info.name.startswith(args.prefix):