diff options
author | Emily Shaffer <emilyshaffer@google.com> | 2019-10-01 00:03:55 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2019-10-02 07:56:54 +0200 |
commit | 65904b8b2b27c71a96d8a9c37c19bcc8f2d1380c (patch) | |
tree | be344801a58957b8f19b2eb9de64f213da643065 /promisor-remote.c | |
parent | promisor-remote.h: drop extern from function declaration (diff) | |
download | git-65904b8b2b27c71a96d8a9c37c19bcc8f2d1380c.tar.xz git-65904b8b2b27c71a96d8a9c37c19bcc8f2d1380c.zip |
promisor-remote: skip move_to_tail when no-op
Previously, when promisor_remote_move_to_tail() is called for a
promisor_remote which is currently the final element in promisors, a
cycle is created in the promisors linked list. This cycle leads to a
double free later on in promisor_remote_clear() when the final element
of the promisors list is removed: promisors is set to promisors->next (a
no-op, as promisors->next == promisors); the previous value of promisors
is free()'d; then the new value of promisors (which is equal to the
previous value of promisors) is also free()'d. This double-free error
was unrecoverable for the user without removing the filter or re-cloning
the repo and hoping to miss this edge case.
Now, when promisor_remote_move_to_tail() would be a no-op, just do a
no-op. In cases of promisor_remote_move_to_tail() where r is not already
at the tail of the list, it works as before.
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
Acked-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'promisor-remote.c')
-rw-r--r-- | promisor-remote.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/promisor-remote.c b/promisor-remote.c index 9bc296cdde..9bd5b79d59 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -89,6 +89,9 @@ static struct promisor_remote *promisor_remote_lookup(const char *remote_name, static void promisor_remote_move_to_tail(struct promisor_remote *r, struct promisor_remote *previous) { + if (r->next == NULL) + return; + if (previous) previous->next = r->next; else |