mirror of
https://github.com/borgbackup/borg.git
synced 2024-12-24 16:55:36 +00:00
better validation of item metadata dicts, fixes #1130
the previous check only checked that we got a dict, but did not validate the dict keys. this triggered issues with e.g. (invalid) integer keys. now it validates the keys: - some required keys must be present - the set of keys is a subset of all valid keys
This commit is contained in:
parent
78121a8d04
commit
a7b5165149
1 changed files with 12 additions and 3 deletions
|
@ -591,6 +591,9 @@ def _open_rb(path):
|
|||
b'mode', b'user', b'group', b'uid', b'gid', b'mtime', b'atime', b'ctime',
|
||||
b'xattrs', b'bsdflags', b'acl_nfs4', b'acl_access', b'acl_default', b'acl_extended', ])
|
||||
|
||||
# this is the set of keys that are always present in items:
|
||||
REQUIRED_ITEM_KEYS = frozenset([b'path', b'mtime', ])
|
||||
|
||||
|
||||
def valid_msgpacked_item(d, item_keys_serialized):
|
||||
"""check if the data <d> looks like a msgpacked item metadata dict"""
|
||||
|
@ -811,8 +814,8 @@ def robust_iterator(archive):
|
|||
|
||||
Missing item chunks will be skipped and the msgpack stream will be restarted
|
||||
"""
|
||||
unpacker = RobustUnpacker(lambda item: isinstance(item, dict) and b'path' in item,
|
||||
self.manifest.item_keys)
|
||||
item_keys = self.manifest.item_keys
|
||||
unpacker = RobustUnpacker(lambda item: isinstance(item, dict) and b'path' in item, item_keys)
|
||||
_state = 0
|
||||
|
||||
def missing_chunk_detector(chunk_id):
|
||||
|
@ -827,6 +830,12 @@ def report(msg, chunk_id, chunk_no):
|
|||
self.error_found = True
|
||||
logger.error(msg)
|
||||
|
||||
def valid_item(obj):
|
||||
if not isinstance(obj, StableDict):
|
||||
return False
|
||||
keys = set(obj)
|
||||
return REQUIRED_ITEM_KEYS.issubset(keys) and keys.issubset(item_keys)
|
||||
|
||||
i = 0
|
||||
for state, items in groupby(archive[b'items'], missing_chunk_detector):
|
||||
items = list(items)
|
||||
|
@ -841,7 +850,7 @@ def report(msg, chunk_id, chunk_no):
|
|||
unpacker.feed(self.key.decrypt(chunk_id, cdata))
|
||||
try:
|
||||
for item in unpacker:
|
||||
if isinstance(item, dict):
|
||||
if valid_item(item):
|
||||
yield item
|
||||
else:
|
||||
report('Did not get expected metadata dict when unpacking item metadata', chunk_id, i)
|
||||
|
|
Loading…
Reference in a new issue