From f4b3536b9b728c0340075ed481036ae01bd493ae Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 6 Nov 2025 12:25:55 +0100 Subject: [PATCH] spa: enforce max values for choice as well Make sure we don't return more values than expected for the choice type. Fixes #4964 --- spa/include/spa/pod/body.h | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/spa/include/spa/pod/body.h b/spa/include/spa/pod/body.h index 51f8e8f74..19edf42d1 100644 --- a/spa/include/spa/pod/body.h +++ b/spa/include/spa/pod/body.h @@ -78,25 +78,34 @@ 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) +SPA_API_POD_BODY int spa_pod_choice_n_values(uint32_t choice_type, uint32_t *min, uint32_t *max) { switch (choice_type) { case SPA_CHOICE_Enum: - return 2; + *min = 2; + *max = UINT32_MAX; + break; case SPA_CHOICE_Range: - return 3; + *min = *max = 3; + break; case SPA_CHOICE_Step: - return 4; + *min = *max = 4; + break; case SPA_CHOICE_None: case SPA_CHOICE_Flags: + *min = *max = 1; + break; default: /* * This must always return at least 1, because callers - * assume that n_vals >= spa_pod_choice_min_values() + * assume that n_vals >= spa_pod_choice_n_values() * mean that n_vals is at least 1. */ - return 1; + *min = 1; + *max = UINT32_MAX; + return 0; } + return 1; } SPA_API_POD_BODY int spa_pod_body_from_data(void *data, size_t maxsize, off_t offset, size_t size, @@ -389,14 +398,16 @@ SPA_API_POD_BODY const void *spa_pod_choice_body_get_values(const struct spa_pod const void *body, uint32_t *n_values, uint32_t *choice, uint32_t *val_size, uint32_t *val_type) { - uint32_t child_size = pod->body.child.size; + uint32_t child_size = pod->body.child.size, min, max; *val_size = child_size; *val_type = pod->body.child.type; *n_values = child_size ? (pod->pod.size - sizeof(pod->body)) / child_size : 0; *choice = pod->body.type; - if (*n_values < spa_pod_choice_min_values(*choice) || - *val_size < spa_pod_type_size(*val_type)) + spa_pod_choice_n_values(*choice, &min, &max); + if (*n_values < min || *val_size < spa_pod_type_size(*val_type)) *n_values = 0; + else if (*n_values > max) + *n_values = max; return body; }