From: Michihiro NAKAJIMA Date: Thu, 11 Feb 2010 04:52:45 +0000 (-0500) Subject: Sanity check of adding sparse info. X-Git-Tag: v3.0.0a~1267 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0c821fe169dd212632fb427e136117c68b6dedd3;p=thirdparty%2Flibarchive.git Sanity check of adding sparse info. SVN-Revision: 1893 --- diff --git a/libarchive/archive_entry.c b/libarchive/archive_entry.c index a45939283..445be04a6 100644 --- a/libarchive/archive_entry.c +++ b/libarchive/archive_entry.c @@ -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); } diff --git a/libarchive/archive_entry_private.h b/libarchive/archive_entry_private.h index 6da775efa..704075d62 100644 --- a/libarchive/archive_entry_private.h +++ b/libarchive/archive_entry_private.h @@ -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. */ diff --git a/libarchive/archive_entry_sparse.c b/libarchive/archive_entry_sparse.c index 3e142feda..530cab71a 100644 --- a/libarchive/archive_entry_sparse.c +++ b/libarchive/archive_entry_sparse.c @@ -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; + } }