mirror of
https://github.com/theupdateframework/python-tuf
synced 2026-05-24 10:08:28 +00:00
Merge branch 'tighten-preorder-dfs' of https://github.com/trishankkarthik/tuf into trishankkarthik-tighten-preorder-dfs
This commit is contained in:
commit
a048ca1630
2 changed files with 29 additions and 9 deletions
|
|
@ -2456,26 +2456,32 @@ def _preorder_depth_first_walk(self, target_filepath):
|
||||||
target = None
|
target = None
|
||||||
current_metadata = self.metadata['current']
|
current_metadata = self.metadata['current']
|
||||||
role_names = ['targets']
|
role_names = ['targets']
|
||||||
|
visited_role_names = set()
|
||||||
|
number_of_delegations = tuf.conf.MAX_NUMBER_OF_DELEGATIONS
|
||||||
|
|
||||||
# Ensure the client has the most up-to-date version of 'targets.json'.
|
# Ensure the client has the most up-to-date version of 'targets.json'.
|
||||||
# Raise 'tuf.NoWorkingMirrorError' if the changed metadata cannot be
|
# Raise 'tuf.NoWorkingMirrorError' if the changed metadata cannot be
|
||||||
# successfully downloaded and 'tuf.RepositoryError' if the referenced
|
# successfully downloaded and 'tuf.RepositoryError' if the referenced
|
||||||
# metadata is missing. Target methods such as this one are called after the
|
# metadata is missing. Target methods such as this one are called after
|
||||||
# top-level metadata have been refreshed (i.e., updater.refresh()).
|
# the top-level metadata have been refreshed (i.e., updater.refresh()).
|
||||||
self._update_metadata_if_changed('targets')
|
self._update_metadata_if_changed('targets')
|
||||||
|
|
||||||
# Preorder depth-first traversal of the tree of target delegations.
|
# Preorder depth-first traversal of the tree of target delegations.
|
||||||
while len(role_names) > 0 and target is None:
|
while target is None and number_of_delegations > 0 and len(role_names) > 0:
|
||||||
|
|
||||||
# Pop the role name from the top of the stack.
|
# Pop the role name from the top of the stack.
|
||||||
role_name = role_names.pop(-1)
|
role_name = role_names.pop(-1)
|
||||||
|
# Skip any visited current role.
|
||||||
|
if role_name in visited_role_names:
|
||||||
|
logger.debug('Skipping visited current role '+repr(role_name))
|
||||||
|
continue
|
||||||
|
|
||||||
# The metadata for 'role_name' must be downloaded/updated before
|
# The metadata for 'role_name' must be downloaded/updated before its
|
||||||
# its targets, delegations, and child roles can be inspected.
|
# targets, delegations, and child roles can be inspected.
|
||||||
# self.metadata['current'][role_name] is currently missing.
|
# self.metadata['current'][role_name] is currently missing.
|
||||||
# _refresh_targets_metadata() does not refresh 'targets.json', it
|
# _refresh_targets_metadata() does not refresh 'targets.json', it expects
|
||||||
# expects _update_metadata_if_changed() to have already refreshed it,
|
# _update_metadata_if_changed() to have already refreshed it, which this
|
||||||
# which this function has checked above.
|
# function has checked above.
|
||||||
self._refresh_targets_metadata(role_name, include_delegations=False)
|
self._refresh_targets_metadata(role_name, include_delegations=False)
|
||||||
|
|
||||||
role_metadata = current_metadata[role_name]
|
role_metadata = current_metadata[role_name]
|
||||||
|
|
@ -2484,6 +2490,10 @@ def _preorder_depth_first_walk(self, target_filepath):
|
||||||
child_roles = delegations.get('roles', [])
|
child_roles = delegations.get('roles', [])
|
||||||
target = self._get_target_from_targets_role(role_name, targets,
|
target = self._get_target_from_targets_role(role_name, targets,
|
||||||
target_filepath)
|
target_filepath)
|
||||||
|
# After preorder check, add current role to set of visited roles.
|
||||||
|
visited_role_names.add(role_name)
|
||||||
|
# And also decrement number of visited roles.
|
||||||
|
number_of_delegations -= 1
|
||||||
|
|
||||||
if target is None:
|
if target is None:
|
||||||
|
|
||||||
|
|
@ -2506,13 +2516,19 @@ def _preorder_depth_first_walk(self, target_filepath):
|
||||||
child_roles_to_visit.append(child_role_name)
|
child_roles_to_visit.append(child_role_name)
|
||||||
|
|
||||||
# Push 'child_roles_to_visit' in reverse order of appearance onto
|
# Push 'child_roles_to_visit' in reverse order of appearance onto
|
||||||
# 'role_names'. Roles are popped from the end of the 'role_names' list.
|
# 'role_names'. Roles are popped from the end of the 'role_names'
|
||||||
|
# list.
|
||||||
child_roles_to_visit.reverse()
|
child_roles_to_visit.reverse()
|
||||||
role_names.extend(child_roles_to_visit)
|
role_names.extend(child_roles_to_visit)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.debug('Found target in current role '+repr(role_name))
|
logger.debug('Found target in current role '+repr(role_name))
|
||||||
|
|
||||||
|
if target is None and number_of_delegations == 0 and len(role_names) > 0:
|
||||||
|
logger.debug(repr(len(role_names))+' roles left to visit, '+
|
||||||
|
'but allowed to visit at most '+
|
||||||
|
repr(tuf.conf.MAX_NUMBER_OF_DELEGATIONS)+' delegations.')
|
||||||
|
|
||||||
return target
|
return target
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,3 +131,7 @@
|
||||||
# the ['http', 'https'] URI schemes are supported, but may be modified by
|
# the ['http', 'https'] URI schemes are supported, but may be modified by
|
||||||
# integrators to schemes that they wish to support for their integration.
|
# integrators to schemes that they wish to support for their integration.
|
||||||
SUPPORTED_URI_SCHEMES = ['http', 'https']
|
SUPPORTED_URI_SCHEMES = ['http', 'https']
|
||||||
|
|
||||||
|
# By default, limit number of delegatees we visit for any target.
|
||||||
|
MAX_NUMBER_OF_DELEGATIONS = 2**5
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue