]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Clean up some memory-management issues in the link resolver.
authorTim Kientzle <kientzle@gmail.com>
Sat, 3 May 2008 15:11:31 +0000 (11:11 -0400)
committerTim Kientzle <kientzle@gmail.com>
Sat, 3 May 2008 15:11:31 +0000 (11:11 -0400)
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

index 0df9ff92e6855d586ad61c82621d8212a6719a04..70c470c3b1ba2d22b62a9fe8097a5f361e4cd502 100644 (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);
 }