Merge pull request #3127 from shxz9u/fix-callback-data-realloc
Avoid updating allocation state before realloc succeeds
This commit is contained in:
4 files changed
+41
-16
No files matched your search
@@ -1698,15 +1698,22 @@ add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id)
|
||||
|
||||
if (ids->count + 1 >= ids->size) {
|
||||
void *p;
|
||||
size_t new_size;
|
||||
|
||||
if (ids->size == 0)
|
||||
ids->size = 8;
|
||||
else
|
||||
ids->size *= 2;
|
||||
p = realloc(ids->ids, sizeof(*ids->ids) * ids->size);
|
||||
new_size = 8;
|
||||
else {
|
||||
if (ids->size > SIZE_MAX / 2)
|
||||
return (error_nomem(a));
|
||||
new_size = ids->size * 2;
|
||||
}
|
||||
if (new_size > SIZE_MAX / sizeof(*ids->ids))
|
||||
return (error_nomem(a));
|
||||
p = realloc(ids->ids, sizeof(*ids->ids) * new_size);
|
||||
if (p == NULL)
|
||||
return (error_nomem(a));
|
||||
ids->ids = (int64_t *)p;
|
||||
ids->size = new_size;
|
||||
}
|
||||
|
||||
/* Find an insert point. */
|
||||
|
||||
@@ -36,6 +36,9 @@
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
@@ -401,6 +404,7 @@ archive_read_add_callback_data(struct archive *_a, void *client_data,
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
void *p;
|
||||
unsigned int i;
|
||||
unsigned int nodes;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
|
||||
"archive_read_add_callback_data");
|
||||
@@ -409,14 +413,26 @@ archive_read_add_callback_data(struct archive *_a, void *client_data,
|
||||
"Invalid index specified");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
p = realloc(a->client.dataset, sizeof(*a->client.dataset)
|
||||
* (++(a->client.nodes)));
|
||||
|
||||
if (a->client.nodes == UINT_MAX ||
|
||||
(size_t)a->client.nodes + 1 >
|
||||
SIZE_MAX / sizeof(*a->client.dataset)) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"No memory");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
nodes = a->client.nodes + 1;
|
||||
p = realloc(a->client.dataset, sizeof(*a->client.dataset) * nodes);
|
||||
if (p == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"No memory");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
a->client.dataset = (struct archive_read_data_node *)p;
|
||||
a->client.nodes = nodes;
|
||||
|
||||
for (i = a->client.nodes - 1; i > iindex; i--) {
|
||||
a->client.dataset[i].data = a->client.dataset[i-1].data;
|
||||
a->client.dataset[i].begin_position = -1;
|
||||
|
||||
@@ -1413,18 +1413,18 @@ update_current_filesystem(struct archive_read_disk *a, int64_t dev)
|
||||
/*
|
||||
* This is the new filesystem which we have to generate a new ID for.
|
||||
*/
|
||||
fid = t->max_filesystem_id++;
|
||||
if (fid > MAX_FILESYSTEM_ID) {
|
||||
fid = t->max_filesystem_id;
|
||||
if (fid >= MAX_FILESYSTEM_ID) {
|
||||
archive_set_error(&a->archive, ENOMEM, "Too many filesystems");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (t->max_filesystem_id > t->allocated_filesystem) {
|
||||
if (fid + 1 > t->allocated_filesystem) {
|
||||
int s;
|
||||
void *p;
|
||||
|
||||
s = t->max_filesystem_id * 2;
|
||||
s = (fid + 1) * 2;
|
||||
p = realloc(t->filesystem_table,
|
||||
s * sizeof(*t->filesystem_table));
|
||||
s * sizeof(*t->filesystem_table));
|
||||
if (p == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate tar data");
|
||||
@@ -1433,6 +1433,7 @@ update_current_filesystem(struct archive_read_disk *a, int64_t dev)
|
||||
t->filesystem_table = (struct filesystem *)p;
|
||||
t->allocated_filesystem = s;
|
||||
}
|
||||
t->max_filesystem_id = fid + 1;
|
||||
t->current_filesystem_id = fid;
|
||||
t->current_filesystem = &(t->filesystem_table[fid]);
|
||||
t->current_filesystem->dev = dev;
|
||||
|
||||
@@ -1452,18 +1452,18 @@ update_current_filesystem(struct archive_read_disk *a, int64_t dev)
|
||||
/*
|
||||
* There is a new filesystem, we generate a new ID for.
|
||||
*/
|
||||
fid = t->max_filesystem_id++;
|
||||
if (fid > MAX_FILESYSTEM_ID) {
|
||||
fid = t->max_filesystem_id;
|
||||
if (fid >= MAX_FILESYSTEM_ID) {
|
||||
archive_set_error(&a->archive, ENOMEM, "Too many filesystems");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (t->max_filesystem_id > t->allocated_filesystem) {
|
||||
if (fid + 1 > t->allocated_filesystem) {
|
||||
int s;
|
||||
void *p;
|
||||
|
||||
s = t->max_filesystem_id * 2;
|
||||
s = (fid + 1) * 2;
|
||||
p = realloc(t->filesystem_table,
|
||||
s * sizeof(*t->filesystem_table));
|
||||
s * sizeof(*t->filesystem_table));
|
||||
if (p == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate tar data");
|
||||
@@ -1472,6 +1472,7 @@ update_current_filesystem(struct archive_read_disk *a, int64_t dev)
|
||||
t->filesystem_table = (struct filesystem *)p;
|
||||
t->allocated_filesystem = s;
|
||||
}
|
||||
t->max_filesystem_id = fid + 1;
|
||||
t->current_filesystem_id = fid;
|
||||
t->current_filesystem = &(t->filesystem_table[fid]);
|
||||
t->current_filesystem->dev = dev;
|
||||
|
||||
Reference in new issue
Block a user