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
This commit is contained in:
Tim Kientzle committed 2008-05-03 11:11:31 -04:00
1 parent ce74796188
commit 981aa07f9d
1 file changed
+13 -7
+13 -7
View File
@@ -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);
}