introuce a hard limit on recursion through symbolic references
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
diff --git a/lib/reference.c b/lib/reference.c
index 5f009d7..eb58d3c 100644
--- a/lib/reference.c
+++ b/lib/reference.c
@@ -64,6 +64,8 @@ struct got_symref {
char *ref;
};
+#define GOT_REF_RECURSE_MAX 20
+
/* A non-symbolic reference (there is no better designation). */
struct got_ref {
char *name;
@@ -545,17 +547,21 @@ resolve_symbolic_ref(struct got_reference **resolved,
return err;
}
-const struct got_error *
-got_ref_resolve(struct got_object_id **id, struct got_repository *repo,
- struct got_reference *ref)
+static const struct got_error *
+ref_resolve(struct got_object_id **id, struct got_repository *repo,
+ struct got_reference *ref, int recursion)
{
const struct got_error *err;
+ if (recursion <= 0)
+ return got_error_msg(GOT_ERR_RECURSION,
+ "reference recursion limit reached");
+
if (ref->flags & GOT_REF_IS_SYMBOLIC) {
struct got_reference *resolved = NULL;
err = resolve_symbolic_ref(&resolved, repo, ref);
if (err == NULL)
- err = got_ref_resolve(id, repo, resolved);
+ err = ref_resolve(id, repo, resolved, --recursion);
if (resolved)
got_ref_close(resolved);
return err;
@@ -568,6 +574,13 @@ got_ref_resolve(struct got_object_id **id, struct got_repository *repo,
return NULL;
}
+const struct got_error *
+got_ref_resolve(struct got_object_id **id, struct got_repository *repo,
+ struct got_reference *ref)
+{
+ return ref_resolve(id, repo, ref, GOT_REF_RECURSE_MAX);
+}
+
char *
got_ref_to_str(struct got_reference *ref)
{