]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Sanity check of adding sparse info.
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Thu, 11 Feb 2010 04:52:45 +0000 (23:52 -0500)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Thu, 11 Feb 2010 04:52:45 +0000 (23:52 -0500)
SVN-Revision: 1893

libarchive/archive_entry.c
libarchive/archive_entry_private.h
libarchive/archive_entry_sparse.c

index a45939283eb9fe814a2f7a60134597203a1b7e07..445be04a6acd212688cab6eb0dc58211b164fc34 100644 (file)
@@ -401,7 +401,6 @@ archive_entry_clear(struct archive_entry *entry)
        archive_entry_sparse_clear(entry);
        free(entry->stat);
        memset(entry, 0, sizeof(*entry));
-       entry->sparse_tail = &(entry->sparse_head);
        return entry;
 }
 
@@ -475,7 +474,6 @@ archive_entry_new(void)
        if (entry == NULL)
                return (NULL);
        memset(entry, 0, sizeof(*entry));
-       entry->sparse_tail = &(entry->sparse_head);
        return (entry);
 }
 
index 6da775efa31450bc8b7ff13032a80bb988014cc1..704075d626a6feab9b99a207dbb4be052b3daba0 100644 (file)
@@ -185,7 +185,7 @@ struct archive_entry {
 
        /* sparse support. */
        struct ae_sparse *sparse_head;
-       struct ae_sparse **sparse_tail;
+       struct ae_sparse *sparse_tail;
        struct ae_sparse *sparse_p;
 
        /* Miscellaneous. */
index 3e142feda79a6795d7dcb8a74b0ea38d0f7fef54..530cab71aa89df6f3bbec0de1f0aecfcaa84407c 100644 (file)
@@ -46,7 +46,7 @@ archive_entry_sparse_clear(struct archive_entry *entry)
                free(entry->sparse_head);
                entry->sparse_head = sp;
        }
-       entry->sparse_tail = &(entry->sparse_head);
+       entry->sparse_tail = NULL;
 }
 
 void
@@ -55,6 +55,28 @@ archive_entry_sparse_add_entry(struct archive_entry *entry,
 {
        struct ae_sparse *sp;
 
+       if (offset < 0 || length < 0)
+               /* Invalid value */
+               return;
+       if (offset + length < 0 ||
+           offset + length > archive_entry_size(entry))
+               /* A value of "length" parameter is too large. */
+               return;
+       if ((sp = entry->sparse_tail) != NULL) {
+               if (sp->offset + sp->length > offset)
+                       /* Invalid value. */
+                       return;
+               if (sp->offset + sp->length == offset) {
+                       if (sp->offset + sp->length + length < 0)
+                               /* A value of "length" parameter is
+                                * too large. */
+                               return;
+                       /* Expand existing sparse block size. */
+                       sp->length += length;
+                       return;
+               }
+       }
+
        if ((sp = (struct ae_sparse *)malloc(sizeof(*sp))) == NULL)
                /* XXX Error XXX */
                return;
@@ -63,8 +85,13 @@ archive_entry_sparse_add_entry(struct archive_entry *entry,
        sp->length = length;
        sp->next = NULL;
 
-       *entry->sparse_tail = sp;
-       entry->sparse_tail = &(sp->next);
+       if (entry->sparse_head == NULL)
+               entry->sparse_head = entry->sparse_tail = sp;
+       else {
+               /* Add a new sparse block to the tail of list. */
+               entry->sparse_tail->next = sp;
+               entry->sparse_tail = sp;
+       }
 }