https://bugzilla.redhat.com/show_bug.cgi?id=705849 http://code.google.com/p/libarchive/source/detail?r=3158&path=/trunk/libarchive/archive_read_support_format_iso9660.c --- libarchive/archive_read_support_format_iso9660.c 2010-03-07 18:07:40.000000000 +0000 +++ libarchive/archive_read_support_format_iso9660.c.oden 2011-12-18 13:52:34.000000000 +0000 @@ -405,12 +405,12 @@ static inline void cache_add_entry(struc static inline void cache_add_to_next_of_parent(struct iso9660 *iso9660, struct file_info *file); static inline struct file_info *cache_get_entry(struct iso9660 *iso9660); -static void heap_add_entry(struct heap_queue *heap, +static int heap_add_entry(struct archive_read *a, struct heap_queue *heap, struct file_info *file, uint64_t key); static struct file_info *heap_get_entry(struct heap_queue *heap); -#define add_entry(iso9660, file) \ - heap_add_entry(&((iso9660)->pending_files), file, file->offset) +#define add_entry(arch, iso9660, file) \ + heap_add_entry(arch, &((iso9660)->pending_files), file, file->offset) #define next_entry(iso9660) \ heap_get_entry(&((iso9660)->pending_files)) @@ -968,8 +968,9 @@ read_children(struct archive_read *a, st if (child == NULL) return (ARCHIVE_FATAL); if (child->cl_offset) - heap_add_entry(&(iso9660->cl_files), - child, child->cl_offset); + if (heap_add_entry(a, &(iso9660->cl_files), + child, child->cl_offset) != ARCHIVE_OK) + return (ARCHIVE_FATAL); else { if (child->multi_extent || multi != NULL) { struct content *con; @@ -993,15 +994,19 @@ read_children(struct archive_read *a, st con->next = NULL; *multi->contents.last = con; multi->contents.last = &(con->next); - if (multi == child) - add_entry(iso9660, child); - else { + if (multi == child) { + if (add_entry(a, iso9660, child) + != ARCHIVE_OK) + return (ARCHIVE_FATAL); + } else { multi->size += child->size; if (!child->multi_extent) multi = NULL; } } else - add_entry(iso9660, child); + if (add_entry(a, iso9660, child) + != ARCHIVE_OK) + return (ARCHIVE_FATAL); } } } @@ -1014,7 +1019,8 @@ read_children(struct archive_read *a, st } static int -relocate_dir(struct iso9660 *iso9660, struct file_info *file) +relocate_dir(struct archive_read *a, struct iso9660 *iso9660, + struct file_info *file) { struct file_info *re; @@ -1036,7 +1042,9 @@ relocate_dir(struct iso9660 *iso9660, st return (1); } else /* This case is wrong pattern. */ - heap_add_entry(&(iso9660->re_dirs), re, re->offset); + if (heap_add_entry(a, &(iso9660->re_dirs), re, re->offset) + != ARCHIVE_OK) + return (ARCHIVE_FATAL); return (0); } @@ -1063,20 +1071,23 @@ read_entries(struct archive_read *a) strcmp(file->name.s, ".rr_moved") == 0)) { iso9660->rr_moved = file; } else if (file->re) - heap_add_entry(&(iso9660->re_dirs), file, - file->offset); + if (heap_add_entry(a, &(iso9660->re_dirs), file, + file->offset) != ARCHIVE_OK) + return (ARCHIVE_FATAL); else cache_add_entry(iso9660, file); } if (file != NULL) - add_entry(iso9660, file); + if (add_entry(a, iso9660, file) != ARCHIVE_OK) + return (ARCHIVE_FATAL); if (iso9660->rr_moved != NULL) { /* * Relocate directory which rr_moved has. */ while ((file = heap_get_entry(&(iso9660->cl_files))) != NULL) - relocate_dir(iso9660, file); + if (relocate_dir(a, iso9660, file) != ARCHIVE_OK) + return ARCHIVE_FATAL; /* If rr_moved directory still has children, * Add rr_moved into pending_files to show @@ -1192,7 +1203,8 @@ archive_read_format_iso9660_read_header( iso9660->seenJoliet = seenJoliet; } /* Store the root directory in the pending list. */ - add_entry(iso9660, file); + if (add_entry(a, iso9660, file) != ARCHIVE_OK) + return (ARCHIVE_FATAL); if (iso9660->seenRockridge) { a->archive.archive_format = ARCHIVE_FORMAT_ISO9660_ROCKRIDGE; @@ -2619,8 +2631,8 @@ cache_get_entry(struct iso9660 *iso9660) return (file); } -static void -heap_add_entry(struct heap_queue *heap, struct file_info *file, uint64_t key) +static int +heap_add_entry(struct archive_read *a, struct heap_queue *heap, struct file_info *file, uint64_t key) { uint64_t file_key, parent_key; int hole, parent; @@ -2633,12 +2645,18 @@ heap_add_entry(struct heap_queue *heap, if (heap->allocated < 1024) new_size = 1024; /* Overflow might keep us from growing the list. */ - if (new_size <= heap->allocated) - __archive_errx(1, "Out of memory"); + if (new_size <= heap->allocated) { + archive_set_error(&a->archive, + ENOMEM, "Out of memory"); + return (ARCHIVE_FATAL); + } new_pending_files = (struct file_info **) malloc(new_size * sizeof(new_pending_files[0])); - if (new_pending_files == NULL) - __archive_errx(1, "Out of memory"); + if (new_pending_files == NULL) { + archive_set_error(&a->archive, + ENOMEM, "Out of memory"); + return (ARCHIVE_FATAL); + } memcpy(new_pending_files, heap->files, heap->allocated * sizeof(new_pending_files[0])); if (heap->files != NULL) @@ -2665,6 +2683,8 @@ heap_add_entry(struct heap_queue *heap, hole = parent; } heap->files[0] = file; + + return (ARCHIVE_OK); } static struct file_info *