mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
pod: use _deref and _frame in safe place
In the filter, don't _deref or use _frame before we are going to add more pods to the builder. If we are using a dynamic builder, the dereffed pod might become invalid when the memory is reallocated. Instead, take the offset of the frame and deref later when we are not going to add more things.
This commit is contained in:
parent
ff7fb675f1
commit
ed7398a64a
2 changed files with 16 additions and 9 deletions
|
|
@ -93,7 +93,7 @@ SPA_API_POD_BUILDER void spa_pod_builder_init(struct spa_pod_builder *builder, v
|
|||
}
|
||||
|
||||
SPA_API_POD_BUILDER struct spa_pod *
|
||||
spa_pod_builder_deref(struct spa_pod_builder *builder, uint32_t offset)
|
||||
spa_pod_builder_deref_fallback(struct spa_pod_builder *builder, uint32_t offset, struct spa_pod *fallback)
|
||||
{
|
||||
uint32_t size = builder->size;
|
||||
if (offset + UINT64_C(8) <= size) {
|
||||
|
|
@ -102,7 +102,13 @@ spa_pod_builder_deref(struct spa_pod_builder *builder, uint32_t offset)
|
|||
SPA_POD_IS_VALID(pod))
|
||||
return pod;
|
||||
}
|
||||
return NULL;
|
||||
return fallback;
|
||||
}
|
||||
|
||||
SPA_API_POD_BUILDER struct spa_pod *
|
||||
spa_pod_builder_deref(struct spa_pod_builder *builder, uint32_t offset)
|
||||
{
|
||||
return (struct spa_pod*)spa_pod_builder_deref_fallback(builder, offset, NULL);
|
||||
}
|
||||
|
||||
SPA_API_POD_BUILDER struct spa_pod *
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
|
|||
{
|
||||
const struct spa_pod *v1, *v2;
|
||||
struct spa_pod_choice *nc, dummy;
|
||||
uint32_t j, k, nalt1, nalt2;
|
||||
uint32_t j, k, nalt1, nalt2, nc_offs;
|
||||
void *alt1, *alt2, *a1, *a2;
|
||||
uint32_t type, size, p1c, p2c;
|
||||
struct spa_pod_frame f;
|
||||
|
|
@ -98,12 +98,10 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
|
|||
|
||||
/* start with copying the property */
|
||||
spa_pod_builder_prop(b, p1->key, p1->flags & p2->flags);
|
||||
spa_pod_builder_push_choice(b, &f, 0, 0);
|
||||
nc = (struct spa_pod_choice*)spa_pod_builder_frame(b, &f);
|
||||
/* write to dummy value when builder overflows. We don't want to error
|
||||
* because overflowing is a way to determine the required buffer size. */
|
||||
if (nc == NULL)
|
||||
nc = &dummy;
|
||||
spa_pod_builder_push_choice(b, &f, SPA_CHOICE_None, 0);
|
||||
spa_zero(dummy);
|
||||
|
||||
nc_offs = f.offset;
|
||||
|
||||
/* start with an empty child and we will select a good default
|
||||
* below */
|
||||
|
|
@ -221,6 +219,7 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
|
|||
spa_pod_builder_raw(b, a1, size);
|
||||
spa_pod_builder_raw(b, min1, size);
|
||||
spa_pod_builder_raw(b, max1, size);
|
||||
nc = (struct spa_pod_choice*)spa_pod_builder_deref_fallback(b, nc_offs, &dummy.pod);
|
||||
nc->body.type = SPA_CHOICE_Range;
|
||||
}
|
||||
else if ((p1c == SPA_CHOICE_None && p2c == SPA_CHOICE_Flags) ||
|
||||
|
|
@ -228,6 +227,7 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
|
|||
(p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_Flags)) {
|
||||
if (spa_pod_filter_flags_value(b, type, alt1, alt2, size) != 1)
|
||||
return -EINVAL;
|
||||
nc = (struct spa_pod_choice*)spa_pod_builder_deref_fallback(b, nc_offs, &dummy.pod);
|
||||
nc->body.type = SPA_CHOICE_Flags;
|
||||
}
|
||||
else if (p1c == SPA_CHOICE_Range && p2c == SPA_CHOICE_Flags)
|
||||
|
|
@ -243,6 +243,7 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
|
|||
else if (p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_Enum)
|
||||
return -ENOTSUP;
|
||||
|
||||
nc = (struct spa_pod_choice*)spa_pod_builder_deref_fallback(b, nc_offs, &dummy.pod);
|
||||
if (nc->body.type == SPA_CHOICE_None) {
|
||||
if (n_copied == 0) {
|
||||
return -EINVAL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue