diff options
author | Mike Isely <isely@pobox.com> | 2008-04-22 14:45:38 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 14:07:47 -0300 |
commit | fdf256f3374d5060e3714651b45b8450b7dc4349 (patch) | |
tree | 3489f5c09d069a4ef4454882c6e3835bf1ddb722 | |
parent | bedbbf8be2f28c9f8a8cf1e2ead4fda8b5f47103 (diff) |
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: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-ctrl.c | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c index 5a3e8d21a38..91a42f2473a 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c @@ -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(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 { int lim; 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) if (cptr->info->set_value) { if (cptr->info->type == pvr2_ctl_bitmask) { 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); 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) { break; } @@ -204,8 +204,7 @@ int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val, if (cptr->info->type == pvr2_ctl_enum) { const char **names; names = cptr->info->def.type_enum.value_names; - if ((val >= 0) && - (val < cptr->info->def.type_enum.count)) { + if (pvr2_ctrl_range_check(cptr,val) == 0) { if (names[val]) { *blen = scnprintf( bptr,bmax,"%s", @@ -528,10 +527,8 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, ptr,len,valptr, cptr->info->def.type_enum.value_names, cptr->info->def.type_enum.count); - if ((ret >= 0) && - ((*valptr < 0) || - (*valptr >= cptr->info->def.type_enum.count))) { - ret = -ERANGE; + if (ret >= 0) { + ret = pvr2_ctrl_range_check(cptr,*valptr); } if (maskptr) *maskptr = ~0; } else if (cptr->info->type == pvr2_ctl_bitmask) { |