core: Limit recursion during traversal

The related objects commit introduced OSTREE_MAX_RECURSION; use it.
This commit is contained in:
Colin Walters 2012-05-15 17:49:59 -04:00
parent cd38cb1489
commit cf53ed5cef
1 changed files with 69 additions and 43 deletions

View File

@ -34,9 +34,10 @@ ostree_traverse_new_reachable (void)
(GDestroyNotify)g_variant_unref, NULL); (GDestroyNotify)g_variant_unref, NULL);
} }
gboolean static gboolean
ostree_traverse_dirtree (OstreeRepo *repo, traverse_dirtree_internal (OstreeRepo *repo,
const char *dirtree_checksum, const char *dirtree_checksum,
int recursion_depth,
GHashTable *inout_reachable, GHashTable *inout_reachable,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
@ -52,6 +53,13 @@ ostree_traverse_dirtree (OstreeRepo *repo,
ot_lvariant GVariant *metadata_csum_v = NULL; ot_lvariant GVariant *metadata_csum_v = NULL;
ot_lfree char *tmp_checksum = NULL; ot_lfree char *tmp_checksum = NULL;
if (recursion_depth > OSTREE_MAX_RECURSION)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Maximum recursion limit reached during traversal");
goto out;
}
if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_DIR_TREE, dirtree_checksum, &tree, error)) if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_DIR_TREE, dirtree_checksum, &tree, error))
goto out; goto out;
@ -90,8 +98,8 @@ ostree_traverse_dirtree (OstreeRepo *repo,
g_free (tmp_checksum); g_free (tmp_checksum);
tmp_checksum = ostree_checksum_from_bytes_v (content_csum_v); tmp_checksum = ostree_checksum_from_bytes_v (content_csum_v);
if (!ostree_traverse_dirtree (repo, tmp_checksum, inout_reachable, if (!traverse_dirtree_internal (repo, tmp_checksum, recursion_depth + 1,
cancellable, error)) inout_reachable, cancellable, error))
goto out; goto out;
g_free (tmp_checksum); g_free (tmp_checksum);
@ -107,6 +115,17 @@ ostree_traverse_dirtree (OstreeRepo *repo,
return ret; return ret;
} }
gboolean
ostree_traverse_dirtree (OstreeRepo *repo,
const char *dirtree_checksum,
GHashTable *inout_reachable,
GCancellable *cancellable,
GError **error)
{
return traverse_dirtree_internal (repo, dirtree_checksum, 0,
inout_reachable, cancellable, error);
}
gboolean gboolean
ostree_traverse_commit (OstreeRepo *repo, ostree_traverse_commit (OstreeRepo *repo,
const char *commit_checksum, const char *commit_checksum,
@ -116,12 +135,16 @@ ostree_traverse_commit (OstreeRepo *repo,
GError **error) GError **error)
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
ot_lfree char*tmp_checksum = NULL;
while (TRUE)
{
gboolean recurse = FALSE;
ot_lvariant GVariant *parent_csum_bytes = NULL; ot_lvariant GVariant *parent_csum_bytes = NULL;
ot_lvariant GVariant *meta_csum_bytes = NULL; ot_lvariant GVariant *meta_csum_bytes = NULL;
ot_lvariant GVariant *content_csum_bytes = NULL; ot_lvariant GVariant *content_csum_bytes = NULL;
ot_lvariant GVariant *key = NULL; ot_lvariant GVariant *key = NULL;
ot_lvariant GVariant *commit = NULL; ot_lvariant GVariant *commit = NULL;
ot_lfree char*tmp_checksum = NULL;
/* PARSE OSTREE_SERIALIZED_COMMIT_VARIANT */ /* PARSE OSTREE_SERIALIZED_COMMIT_VARIANT */
if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, commit_checksum, &commit, error)) if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, commit_checksum, &commit, error))
@ -152,12 +175,15 @@ ostree_traverse_commit (OstreeRepo *repo,
{ {
g_free (tmp_checksum); g_free (tmp_checksum);
tmp_checksum = ostree_checksum_from_bytes_v (parent_csum_bytes); tmp_checksum = ostree_checksum_from_bytes_v (parent_csum_bytes);
if (!ostree_traverse_commit (repo, tmp_checksum, commit_checksum = tmp_checksum;
maxdepth > 0 ? maxdepth - 1 : -1, if (maxdepth > 0)
inout_reachable, cancellable, error)) maxdepth -= 1;
goto out; recurse = TRUE;
} }
} }
if (!recurse)
break;
}
ret = TRUE; ret = TRUE;
out: out: