mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
spa: add some more POD tests
Check if the pod size is at least big enough to hold 1 item when getting array or choice items. Check that the number of choice values is at least enough to handle the given choice type. Remove some redundant checks.
This commit is contained in:
parent
77a5100280
commit
95fb03c8e3
4 changed files with 30 additions and 9 deletions
|
|
@ -164,8 +164,7 @@ SPA_API_DEBUG_FORMAT int spa_debugc_format(struct spa_debug_context *ctx, int in
|
|||
type = val->type;
|
||||
size = val->size;
|
||||
|
||||
if (type < SPA_TYPE_None || type >= _SPA_TYPE_LAST || n_vals < 1 ||
|
||||
size < spa_pod_type_size(type))
|
||||
if (type < SPA_TYPE_None || type >= _SPA_TYPE_LAST || n_vals < 1)
|
||||
continue;
|
||||
|
||||
vals = SPA_POD_BODY(val);
|
||||
|
|
|
|||
|
|
@ -78,6 +78,27 @@ SPA_API_POD_BODY uint32_t spa_pod_type_size(uint32_t type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
SPA_API_POD_BODY uint32_t spa_pod_choice_min_values(uint32_t choice_type)
|
||||
{
|
||||
switch (choice_type) {
|
||||
case SPA_CHOICE_Enum:
|
||||
return 2;
|
||||
case SPA_CHOICE_Range:
|
||||
return 3;
|
||||
case SPA_CHOICE_Step:
|
||||
return 4;
|
||||
case SPA_CHOICE_None:
|
||||
case SPA_CHOICE_Flags:
|
||||
default:
|
||||
/*
|
||||
* This must always return at least 1, because callers
|
||||
* assume that n_vals >= spa_pod_choice_min_values()
|
||||
* mean that n_vals is at least 1.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
SPA_API_POD_BODY int spa_pod_body_from_data(void *data, size_t maxsize, off_t offset, size_t size,
|
||||
struct spa_pod *pod, const void **body)
|
||||
{
|
||||
|
|
@ -333,6 +354,8 @@ SPA_API_POD_BODY const void *spa_pod_array_body_get_values(const struct spa_pod_
|
|||
*n_values = child_size ? (arr->pod.size - sizeof(arr->body)) / child_size : 0;
|
||||
*val_size = child_size;
|
||||
*val_type = arr->body.child.type;
|
||||
if (*val_size < spa_pod_type_size(*val_type))
|
||||
*n_values = 0;
|
||||
return body;
|
||||
}
|
||||
|
||||
|
|
@ -371,8 +394,9 @@ SPA_API_POD_BODY const void *spa_pod_choice_body_get_values(const struct spa_pod
|
|||
*val_type = pod->body.child.type;
|
||||
*n_values = child_size ? (pod->pod.size - sizeof(pod->body)) / child_size : 0;
|
||||
*choice = pod->body.type;
|
||||
if (*choice == SPA_CHOICE_None)
|
||||
*n_values = SPA_MIN(1u, *n_values);
|
||||
if (*n_values < spa_pod_choice_min_values(*choice) ||
|
||||
*val_size < spa_pod_type_size(*val_type))
|
||||
*n_values = 0;
|
||||
return body;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
|
|||
v1 = spa_pod_get_values(&p1->value, &nalt1, &p1c);
|
||||
v2 = spa_pod_get_values(&p2->value, &nalt2, &p2c);
|
||||
|
||||
/* empty choices */
|
||||
/* empty/invalid choices */
|
||||
if (nalt1 < 1 || nalt2 < 1)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -95,8 +95,6 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
|
|||
/* incompatible property types */
|
||||
if (type != v2->type || size != v2->size || p1->key != p2->key)
|
||||
return -EINVAL;
|
||||
if (size < spa_pod_type_size(type))
|
||||
return -EINVAL;
|
||||
|
||||
/* start with copying the property */
|
||||
spa_pod_builder_prop(b, p1->key, p1->flags & p2->flags);
|
||||
|
|
@ -406,7 +404,7 @@ SPA_API_POD_FILTER int spa_pod_filter_object_make(struct spa_pod_object *pod)
|
|||
struct spa_pod *v = spa_pod_get_values(&res->value, &nvals, &choice);
|
||||
const void *vals = SPA_POD_BODY(v);
|
||||
|
||||
if (v->size < spa_pod_type_size(v->type))
|
||||
if (nvals < 1)
|
||||
continue;
|
||||
|
||||
if (spa_pod_compare_is_valid_choice(v->type, v->size,
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ SPA_API_POD_ITER struct spa_pod *spa_pod_get_values(const struct spa_pod *pod,
|
|||
spa_pod_choice_body_get_values(p, SPA_POD_BODY_CONST(p), n_vals, choice, &size, &type);
|
||||
return (struct spa_pod*)&p->body.child;
|
||||
} else {
|
||||
*n_vals = 1;
|
||||
*n_vals = pod->size < spa_pod_type_size(pod->type) ? 0 : 1;
|
||||
*choice = SPA_CHOICE_None;
|
||||
return (struct spa_pod*)pod;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue