Commit fdf256f3 authored by Mike Isely's avatar Mike Isely Committed by Mauro Carvalho Chehab

V4L/DVB (7302): pvrusb2: Improve control validation for enumerations

When an enumeration control is changed, the pvrusb2 driver assumed
that the enumeration values were continuous.  That is no longer true;
this change allows for properly input validation even when not all
enumeration values are legal (which can happen with input selection
based on what the hardware supports).
Signed-off-by: default avatarMike Isely <isely@pobox.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent bedbbf8b
...@@ -30,6 +30,9 @@ static int pvr2_ctrl_range_check(struct pvr2_ctrl *cptr,int val) ...@@ -30,6 +30,9 @@ static int pvr2_ctrl_range_check(struct pvr2_ctrl *cptr,int val)
{ {
if (cptr->info->check_value) { if (cptr->info->check_value) {
if (!cptr->info->check_value(cptr,val)) return -ERANGE; if (!cptr->info->check_value(cptr,val)) return -ERANGE;
} else if (cptr->info->type == pvr2_ctl_enum) {
if (val < 0) return -ERANGE;
if (val >= cptr->info->def.type_enum.count) return -ERANGE;
} else { } else {
int lim; int lim;
lim = cptr->info->def.type_int.min_value; lim = cptr->info->def.type_int.min_value;
...@@ -63,13 +66,10 @@ int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val) ...@@ -63,13 +66,10 @@ int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val)
if (cptr->info->set_value) { if (cptr->info->set_value) {
if (cptr->info->type == pvr2_ctl_bitmask) { if (cptr->info->type == pvr2_ctl_bitmask) {
mask &= cptr->info->def.type_bitmask.valid_bits; mask &= cptr->info->def.type_bitmask.valid_bits;
} else if (cptr->info->type == pvr2_ctl_int) { } else if ((cptr->info->type == pvr2_ctl_int)||
(cptr->info->type == pvr2_ctl_enum)) {
ret = pvr2_ctrl_range_check(cptr,val); ret = pvr2_ctrl_range_check(cptr,val);
if (ret < 0) break; if (ret < 0) break;
} else if (cptr->info->type == pvr2_ctl_enum) {
if (val >= cptr->info->def.type_enum.count) {
break;
}
} else if (cptr->info->type != pvr2_ctl_bool) { } else if (cptr->info->type != pvr2_ctl_bool) {
break; break;
} }
...@@ -204,8 +204,7 @@ int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val, ...@@ -204,8 +204,7 @@ int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val,
if (cptr->info->type == pvr2_ctl_enum) { if (cptr->info->type == pvr2_ctl_enum) {
const char **names; const char **names;
names = cptr->info->def.type_enum.value_names; names = cptr->info->def.type_enum.value_names;
if ((val >= 0) && if (pvr2_ctrl_range_check(cptr,val) == 0) {
(val < cptr->info->def.type_enum.count)) {
if (names[val]) { if (names[val]) {
*blen = scnprintf( *blen = scnprintf(
bptr,bmax,"%s", bptr,bmax,"%s",
...@@ -528,10 +527,8 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, ...@@ -528,10 +527,8 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
ptr,len,valptr, ptr,len,valptr,
cptr->info->def.type_enum.value_names, cptr->info->def.type_enum.value_names,
cptr->info->def.type_enum.count); cptr->info->def.type_enum.count);
if ((ret >= 0) && if (ret >= 0) {
((*valptr < 0) || ret = pvr2_ctrl_range_check(cptr,*valptr);
(*valptr >= cptr->info->def.type_enum.count))) {
ret = -ERANGE;
} }
if (maskptr) *maskptr = ~0; if (maskptr) *maskptr = ~0;
} else if (cptr->info->type == pvr2_ctl_bitmask) { } else if (cptr->info->type == pvr2_ctl_bitmask) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment