pkg: prevent circular ownership

Otherwise in a case where A references B, and B references A, A and B
will have mutual ownership of each other and prevent each other from
being free'd.
pull/239/head
Dylan Baker 2022-08-04 15:16:44 -07:00
parent 301d8fa0c6
commit 1cfa2d1e20
1 changed files with 10 additions and 2 deletions

View File

@ -1445,9 +1445,9 @@ pkgconf_pkg_walk_list(pkgconf_client_t *client,
unsigned int skip_flags) unsigned int skip_flags)
{ {
unsigned int eflags = PKGCONF_PKG_ERRF_OK; unsigned int eflags = PKGCONF_PKG_ERRF_OK;
pkgconf_node_t *node; pkgconf_node_t *node, *next;
PKGCONF_FOREACH_LIST_ENTRY(deplist->head, node) PKGCONF_FOREACH_LIST_ENTRY_SAFE(deplist->head, next, node)
{ {
unsigned int eflags_local = PKGCONF_PKG_ERRF_OK; unsigned int eflags_local = PKGCONF_PKG_ERRF_OK;
pkgconf_dependency_t *depnode = node->data; pkgconf_dependency_t *depnode = node->data;
@ -1470,6 +1470,14 @@ pkgconf_pkg_walk_list(pkgconf_client_t *client,
if (pkgdep->serial == client->serial) if (pkgdep->serial == client->serial)
{ {
pkgdep->hits++; pkgdep->hits++;
/* In this case we have a circular reference.
* We break that by deleteing the circular node from the
* the list, so that we dont create a situation where
* memory is leaked due to circular ownership.
* i.e: A owns B owns A
*/
pkgconf_node_delete(node, deplist);
pkgconf_dependency_unref(client, depnode);
goto next; goto next;
} }