From 981aa07f9d85c33ba8e4835379492bc6255ed9c9 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sat, 3 May 2008 11:11:31 -0400 Subject: [PATCH] Clean up some memory-management issues in the link resolver. Now, the 'canonical' entry is the one actually used for matching and lookups, the 'entry' is used for transient needs, and the bookkeeping now correctly tracks when the 'entry' is no longer valid because it was handed back to the client. Obtained from: Joerg Sonnenberger SVN-Revision: 19 --- libarchive/archive_entry_link_resolver.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/libarchive/archive_entry_link_resolver.c b/libarchive/archive_entry_link_resolver.c index 0df9ff92e..70c470c3b 100644 --- a/libarchive/archive_entry_link_resolver.c +++ b/libarchive/archive_entry_link_resolver.c @@ -145,8 +145,10 @@ archive_entry_linkresolver_free(struct archive_entry_linkresolver *res) struct links_entry *le; if (res->buckets != NULL) { - while ((le = next_entry(res)) != NULL) + while ((le = next_entry(res)) != NULL) { archive_entry_free(le->entry); + archive_entry_free(le->canonical); + } free(res->buckets); res->buckets = NULL; } @@ -164,8 +166,10 @@ archive_entry_linkify(struct archive_entry_linkresolver *res, if (*e == NULL) { le = next_entry(res); - if (le != NULL) + if (le != NULL) { *e = le->entry; + le->entry = NULL; + } return; } @@ -202,8 +206,10 @@ archive_entry_linkify(struct archive_entry_linkresolver *res, archive_entry_pathname(le->canonical)); /* If we ran out of links, return the * final entry as well. */ - if (le->links == 0) + if (le->links == 0) { *f = le->entry; + le->entry = NULL; + } } else { /* * If we haven't seen it, tuck it away @@ -232,6 +238,7 @@ find_entry(struct archive_entry_linkresolver *res, /* Free a held entry. */ if (res->spare != NULL) { archive_entry_free(res->spare->canonical); + archive_entry_free(res->spare->entry); free(res->spare); res->spare = NULL; } @@ -248,8 +255,8 @@ find_entry(struct archive_entry_linkresolver *res, bucket = hash % res->number_buckets; for (le = res->buckets[bucket]; le != NULL; le = le->next) { if (le->hash == hash - && dev == archive_entry_dev(le->entry) - && ino == archive_entry_ino(le->entry)) { + && dev == archive_entry_dev(le->canonical) + && ino == archive_entry_ino(le->canonical)) { /* * Decrement link count each time and release * the entry if it hits zero. This saves @@ -320,7 +327,7 @@ insert_entry(struct archive_entry_linkresolver *res, le = malloc(sizeof(struct links_entry)); if (le == NULL) return (NULL); - le->entry = entry; + le->canonical = archive_entry_clone(entry); /* If the links cache is getting too full, enlarge the hash table. */ if (res->number_entries > res->number_buckets * 2) @@ -338,7 +345,6 @@ insert_entry(struct archive_entry_linkresolver *res, res->buckets[bucket] = le; le->hash = hash; le->links = archive_entry_nlink(entry) - 1; - le->canonical = archive_entry_clone(entry); return (le); } -- 2.47.3