1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2024-12-26 09:47:58 +00:00

Item: fix xattr processing

Item.xattrs is now always a StableDict mapping bytes keys -> bytes values.

The special casing of empty values (b'') getting replaced by None was removed.
This commit is contained in:
Thomas Waldmann 2022-05-29 21:22:50 +02:00
parent 9d684120a2
commit 64cc16a9f4
2 changed files with 11 additions and 9 deletions

View file

@ -99,7 +99,7 @@ def want_bytes(v, *, errors='surrogateescape'):
# legacy support: it being str can be caused by msgpack unpack decoding old data that was packed with use_bin_type=False # legacy support: it being str can be caused by msgpack unpack decoding old data that was packed with use_bin_type=False
if isinstance(v, str): if isinstance(v, str):
v = v.encode('utf-8', errors=errors) v = v.encode('utf-8', errors=errors)
assert isinstance(v, bytes) assert isinstance(v, bytes), f'not a bytes object, but {v!r}'
return v return v
@ -107,7 +107,7 @@ def want_str(v, *, errors='surrogateescape'):
"""we know that we want str and the value should be str""" """we know that we want str and the value should be str"""
if isinstance(v, bytes): if isinstance(v, bytes):
v = v.decode('utf-8', errors=errors) v = v.decode('utf-8', errors=errors)
assert isinstance(v, str) assert isinstance(v, str), f'not a str object, but {v!r}'
return v return v
@ -397,7 +397,13 @@ class Item(PropDict):
if k == 'xattrs': if k == 'xattrs':
if not isinstance(v, StableDict): if not isinstance(v, StableDict):
v = StableDict(v) v = StableDict(v)
# TODO: xattrs key/value types v_new = StableDict()
for xk, xv in list(v.items()):
xk = want_bytes(xk)
# old borg used to store None instead of a b'' value
xv = b'' if xv is None else want_bytes(xv)
v_new[xk] = xv
v = v_new # xattrs is a StableDict(bytes keys -> bytes values)
self._dict[k] = v self._dict[k] = v

View file

@ -76,9 +76,7 @@ def get_all(path, follow_symlinks=False):
for name in names: for name in names:
try: try:
# xattr name is a bytes object, we directly use it. # xattr name is a bytes object, we directly use it.
# if we get an empty xattr value (b''), we store None into the result dict - result[name] = getxattr(path, name, follow_symlinks=follow_symlinks)
# borg always did it like that...
result[name] = getxattr(path, name, follow_symlinks=follow_symlinks) or None
except OSError as e: except OSError as e:
name_str = name.decode() name_str = name.decode()
if isinstance(path, int): if isinstance(path, int):
@ -122,9 +120,7 @@ def set_all(path, xattrs, follow_symlinks=False):
warning = False warning = False
for k, v in xattrs.items(): for k, v in xattrs.items():
try: try:
# the key k is a bytes object due to msgpack unpacking it as such. setxattr(path, k, v, follow_symlinks=follow_symlinks)
# if we have a None value, it means "empty", so give b'' to setxattr in that case:
setxattr(path, k, v or b'', follow_symlinks=follow_symlinks)
except OSError as e: except OSError as e:
warning = True warning = True
k_str = k.decode() k_str = k.decode()