audioconvert: handle realloc errors

The original pointer is untouched when realloc fails and returns NULL so
make sure we free the previous values.
This commit is contained in:
Wim Taymans 2023-10-03 20:38:11 +02:00
parent d8c73ebede
commit 48e11c6fe0

View file

@ -2445,6 +2445,53 @@ static inline void dequeue_buffer(struct impl *this, struct port *port, struct b
SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_QUEUED);
}
static void free_tmp(struct impl *this)
{
uint32_t i;
spa_log_warn(this->log, "free tmp %d", this->empty_size);
free(this->empty);
this->empty = NULL;
this->empty_size = 0;
free(this->scratch);
this->scratch = NULL;
free(this->tmp[0]);
this->tmp[0] = NULL;
free(this->tmp[1]);
this->tmp[1] = NULL;
for (i = 0; i < MAX_PORTS; i++) {
this->tmp_datas[0][i] = NULL;
this->tmp_datas[1][i] = NULL;
}
}
static int ensure_tmp(struct impl *this, uint32_t maxsize)
{
if (maxsize > this->empty_size) {
float *empty, *scratch, *tmp[2];
spa_log_warn(this->log, "resize tmp %d -> %d", this->empty_size, maxsize);
if ((empty = realloc(this->empty, maxsize + MAX_ALIGN)) != NULL)
this->empty = empty;
if ((scratch = realloc(this->scratch, maxsize + MAX_ALIGN)) != NULL)
this->scratch = scratch;
if ((tmp[0] = realloc(this->tmp[0], (maxsize + MAX_ALIGN) * MAX_PORTS)) != NULL)
this->tmp[0] = tmp[0];
if ((tmp[1] = realloc(this->tmp[1], (maxsize + MAX_ALIGN) * MAX_PORTS)) != NULL)
this->tmp[1] = tmp[1];
if (empty == NULL || scratch == NULL || tmp[0] == NULL || tmp[1] == NULL) {
free_tmp(this);
return -ENOMEM;
}
memset(this->empty, 0, maxsize + MAX_ALIGN);
this->empty_size = maxsize;
}
return 0;
}
static int
impl_node_port_use_buffers(void *object,
enum spa_direction direction,
@ -2456,6 +2503,7 @@ impl_node_port_use_buffers(void *object,
struct impl *this = object;
struct port *port;
uint32_t i, j, maxsize;
int res;
spa_return_val_if_fail(this != NULL, -EINVAL);
@ -2512,17 +2560,9 @@ impl_node_port_use_buffers(void *object,
if (direction == SPA_DIRECTION_OUTPUT)
queue_buffer(this, port, i);
}
if (maxsize > this->empty_size) {
this->empty = realloc(this->empty, maxsize + MAX_ALIGN);
this->scratch = realloc(this->scratch, maxsize + MAX_ALIGN);
this->tmp[0] = realloc(this->tmp[0], (maxsize + MAX_ALIGN) * MAX_PORTS);
this->tmp[1] = realloc(this->tmp[1], (maxsize + MAX_ALIGN) * MAX_PORTS);
if (this->empty == NULL || this->scratch == NULL ||
this->tmp[0] == NULL || this->tmp[1] == NULL)
return -errno;
memset(this->empty, 0, maxsize + MAX_ALIGN);
this->empty_size = maxsize;
}
if ((res = ensure_tmp(this, maxsize)) < 0)
return res;
port->n_buffers = n_buffers;
return 0;
@ -3250,10 +3290,7 @@ static int impl_clear(struct spa_handle *handle)
free_dir(&this->dir[SPA_DIRECTION_INPUT]);
free_dir(&this->dir[SPA_DIRECTION_OUTPUT]);
free(this->empty);
free(this->scratch);
free(this->tmp[0]);
free(this->tmp[1]);
free_tmp(this);
if (this->resample.free)
resample_free(&this->resample);