mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	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:
		
							parent
							
								
									d8c73ebede
								
							
						
					
					
						commit
						48e11c6fe0
					
				
					 1 changed files with 52 additions and 15 deletions
				
			
		| 
						 | 
					@ -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);
 | 
						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
 | 
					static int
 | 
				
			||||||
impl_node_port_use_buffers(void *object,
 | 
					impl_node_port_use_buffers(void *object,
 | 
				
			||||||
			   enum spa_direction direction,
 | 
								   enum spa_direction direction,
 | 
				
			||||||
| 
						 | 
					@ -2456,6 +2503,7 @@ impl_node_port_use_buffers(void *object,
 | 
				
			||||||
	struct impl *this = object;
 | 
						struct impl *this = object;
 | 
				
			||||||
	struct port *port;
 | 
						struct port *port;
 | 
				
			||||||
	uint32_t i, j, maxsize;
 | 
						uint32_t i, j, maxsize;
 | 
				
			||||||
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_return_val_if_fail(this != NULL, -EINVAL);
 | 
						spa_return_val_if_fail(this != NULL, -EINVAL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2512,17 +2560,9 @@ impl_node_port_use_buffers(void *object,
 | 
				
			||||||
		if (direction == SPA_DIRECTION_OUTPUT)
 | 
							if (direction == SPA_DIRECTION_OUTPUT)
 | 
				
			||||||
			queue_buffer(this, port, i);
 | 
								queue_buffer(this, port, i);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (maxsize > this->empty_size) {
 | 
						if ((res = ensure_tmp(this, maxsize)) < 0)
 | 
				
			||||||
		this->empty = realloc(this->empty, maxsize + MAX_ALIGN);
 | 
							return res;
 | 
				
			||||||
		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;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	port->n_buffers = n_buffers;
 | 
						port->n_buffers = n_buffers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						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_INPUT]);
 | 
				
			||||||
	free_dir(&this->dir[SPA_DIRECTION_OUTPUT]);
 | 
						free_dir(&this->dir[SPA_DIRECTION_OUTPUT]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(this->empty);
 | 
						free_tmp(this);
 | 
				
			||||||
	free(this->scratch);
 | 
					 | 
				
			||||||
	free(this->tmp[0]);
 | 
					 | 
				
			||||||
	free(this->tmp[1]);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (this->resample.free)
 | 
						if (this->resample.free)
 | 
				
			||||||
		resample_free(&this->resample);
 | 
							resample_free(&this->resample);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue