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:
parent
9d684120a2
commit
64cc16a9f4
2 changed files with 11 additions and 9 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in a new issue