@@ -94,7 +94,6 @@ EXPORT_SYMBOL_GPL(hid_register_report);
9494static struct hid_field * hid_register_field (struct hid_report * report , unsigned usages , unsigned values )
9595{
9696 struct hid_field * field ;
97- int i ;
9897
9998 if (report -> maxfield == HID_MAX_FIELDS ) {
10099 hid_err (report -> device , "too many fields in report\n" );
@@ -113,9 +112,6 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned
113112 field -> value = (s32 * )(field -> usage + usages );
114113 field -> report = report ;
115114
116- for (i = 0 ; i < usages ; i ++ )
117- field -> usage [i ].usage_index = i ;
118-
119115 return field ;
120116}
121117
@@ -226,9 +222,9 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
226222{
227223 struct hid_report * report ;
228224 struct hid_field * field ;
229- int usages ;
225+ unsigned usages ;
230226 unsigned offset ;
231- int i ;
227+ unsigned i ;
232228
233229 report = hid_register_report (parser -> device , report_type , parser -> global .report_id );
234230 if (!report ) {
@@ -255,7 +251,8 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
255251 if (!parser -> local .usage_index ) /* Ignore padding fields */
256252 return 0 ;
257253
258- usages = max_t (int , parser -> local .usage_index , parser -> global .report_count );
254+ usages = max_t (unsigned , parser -> local .usage_index ,
255+ parser -> global .report_count );
259256
260257 field = hid_register_field (report , usages , parser -> global .report_count );
261258 if (!field )
@@ -266,13 +263,14 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
266263 field -> application = hid_lookup_collection (parser , HID_COLLECTION_APPLICATION );
267264
268265 for (i = 0 ; i < usages ; i ++ ) {
269- int j = i ;
266+ unsigned j = i ;
270267 /* Duplicate the last usage we parsed if we have excess values */
271268 if (i >= parser -> local .usage_index )
272269 j = parser -> local .usage_index - 1 ;
273270 field -> usage [i ].hid = parser -> local .usage [j ];
274271 field -> usage [i ].collection_index =
275272 parser -> local .collection_index [j ];
273+ field -> usage [i ].usage_index = i ;
276274 }
277275
278276 field -> maxusage = usages ;
@@ -801,6 +799,64 @@ int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size)
801799}
802800EXPORT_SYMBOL_GPL (hid_parse_report );
803801
802+ static const char * const hid_report_names [] = {
803+ "HID_INPUT_REPORT" ,
804+ "HID_OUTPUT_REPORT" ,
805+ "HID_FEATURE_REPORT" ,
806+ };
807+ /**
808+ * hid_validate_values - validate existing device report's value indexes
809+ *
810+ * @device: hid device
811+ * @type: which report type to examine
812+ * @id: which report ID to examine (0 for first)
813+ * @field_index: which report field to examine
814+ * @report_counts: expected number of values
815+ *
816+ * Validate the number of values in a given field of a given report, after
817+ * parsing.
818+ */
819+ struct hid_report * hid_validate_values (struct hid_device * hid ,
820+ unsigned int type , unsigned int id ,
821+ unsigned int field_index ,
822+ unsigned int report_counts )
823+ {
824+ struct hid_report * report ;
825+
826+ if (type > HID_FEATURE_REPORT ) {
827+ hid_err (hid , "invalid HID report type %u\n" , type );
828+ return NULL ;
829+ }
830+
831+ if (id >= HID_MAX_IDS ) {
832+ hid_err (hid , "invalid HID report id %u\n" , id );
833+ return NULL ;
834+ }
835+
836+ /*
837+ * Explicitly not using hid_get_report() here since it depends on
838+ * ->numbered being checked, which may not always be the case when
839+ * drivers go to access report values.
840+ */
841+ report = hid -> report_enum [type ].report_id_hash [id ];
842+ if (!report ) {
843+ hid_err (hid , "missing %s %u\n" , hid_report_names [type ], id );
844+ return NULL ;
845+ }
846+ if (report -> maxfield <= field_index ) {
847+ hid_err (hid , "not enough fields in %s %u\n" ,
848+ hid_report_names [type ], id );
849+ return NULL ;
850+ }
851+ if (report -> field [field_index ]-> report_count < report_counts ) {
852+ hid_err (hid , "not enough values in %s %u field %u\n" ,
853+ hid_report_names [type ], id , field_index );
854+ return NULL ;
855+ }
856+ return report ;
857+ }
858+ EXPORT_SYMBOL_GPL (hid_validate_values );
859+
804860/**
805861 * hid_open_report - open a driver-specific device report
806862 *
@@ -1296,7 +1352,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
12961352 goto out ;
12971353 }
12981354
1299- if (hid -> claimed != HID_CLAIMED_HIDRAW ) {
1355+ if (hid -> claimed != HID_CLAIMED_HIDRAW && report -> maxfield ) {
13001356 for (a = 0 ; a < report -> maxfield ; a ++ )
13011357 hid_input_field (hid , report -> field [a ], cdata , interrupt );
13021358 hdrv = hid -> driver ;
0 commit comments