Forráskód Böngészése

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.
Thomas Waldmann 3 éve
szülő
commit
64cc16a9f4
2 módosított fájl, 11 hozzáadás és 9 törlés
  1. 9 3
      src/borg/item.pyx
  2. 2 6
      src/borg/xattr.py

+ 9 - 3
src/borg/item.pyx

@@ -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
     if isinstance(v, str):
         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
 
 
@@ -107,7 +107,7 @@ def want_str(v, *, errors='surrogateescape'):
     """we know that we want str and the value should be str"""
     if isinstance(v, bytes):
         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
 
 
@@ -397,7 +397,13 @@ class Item(PropDict):
             if k == 'xattrs':
                 if not isinstance(v, StableDict):
                     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
 
 

+ 2 - 6
src/borg/xattr.py

@@ -76,9 +76,7 @@ def get_all(path, follow_symlinks=False):
         for name in names:
             try:
                 # 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 -
-                # borg always did it like that...
-                result[name] = getxattr(path, name, follow_symlinks=follow_symlinks) or None
+                result[name] = getxattr(path, name, follow_symlinks=follow_symlinks)
             except OSError as e:
                 name_str = name.decode()
                 if isinstance(path, int):
@@ -122,9 +120,7 @@ def set_all(path, xattrs, follow_symlinks=False):
     warning = False
     for k, v in xattrs.items():
         try:
-            # the key k is a bytes object due to msgpack unpacking it as such.
-            # 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)
+            setxattr(path, k, v, follow_symlinks=follow_symlinks)
         except OSError as e:
             warning = True
             k_str = k.decode()