[PATCH 2/6] hidclass.sys: Handle failures when parsing descriptor.
Rémi Bernon
rbernon at codeweavers.com
Mon Jun 7 04:06:57 CDT 2021
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/hidclass.sys/descriptor.c | 39 +++++++++++++++++++++++++---------
1 file changed, 29 insertions(+), 10 deletions(-)
diff --git a/dlls/hidclass.sys/descriptor.c b/dlls/hidclass.sys/descriptor.c
index 9c52dee5fe1..0e0d6a6bf54 100644
--- a/dlls/hidclass.sys/descriptor.c
+++ b/dlls/hidclass.sys/descriptor.c
@@ -464,7 +464,7 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
{
int usages_top = 0;
USAGE usages[256];
- unsigned int i;
+ int i;
for (i = index; i < length;)
{
@@ -479,6 +479,7 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
{
/* Long data items: Should be unused */
ERR("Long Data Item, should be unused\n");
+ return -1;
}
else
{
@@ -506,7 +507,7 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
case TAG_MAIN_FEATURE:
for (j = 0; j < caps->ReportCount; j++)
{
- feature = calloc(1, sizeof(*feature));
+ if (!(feature = calloc(1, sizeof(*feature)))) return -1;
list_add_tail(&collection->features, &feature->entry);
if (bTag == TAG_MAIN_INPUT)
feature->type = HidP_Input;
@@ -531,7 +532,8 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
break;
case TAG_MAIN_COLLECTION:
{
- struct collection *subcollection = calloc(1, sizeof(struct collection));
+ struct collection *subcollection;
+ if (!(subcollection = calloc(1, sizeof(struct collection)))) return -1;
list_add_tail(&collection->collections, &subcollection->entry);
subcollection->parent = collection;
/* Only set our collection once...
@@ -552,13 +554,14 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
parse_collection(bSize, itemVal, subcollection);
- i = parse_descriptor(descriptor, i+1, length, feature_index, collection_index, subcollection, caps, stack);
+ if ((i = parse_descriptor(descriptor, i+1, length, feature_index, collection_index, subcollection, caps, stack)) < 0) return i;
continue;
}
case TAG_MAIN_END_COLLECTION:
return i;
default:
ERR("Unknown (bTag: 0x%x, bType: 0x%x)\n", bTag, bType);
+ return -1;
}
}
else if (bType == TAG_TYPE_GLOBAL)
@@ -597,7 +600,8 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
break;
case TAG_GLOBAL_PUSH:
{
- struct caps_stack *saved = malloc(sizeof(*saved));
+ struct caps_stack *saved;
+ if (!(saved = malloc(sizeof(*saved)))) return -1;
saved->caps = *caps;
TRACE("Push\n");
list_add_tail(stack, &saved->entry);
@@ -617,11 +621,15 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
free(saved);
}
else
+ {
ERR("Pop but no stack!\n");
+ return -1;
+ }
break;
}
default:
ERR("Unknown (bTag: 0x%x, bType: 0x%x)\n", bTag, bType);
+ return -1;
}
}
else if (bType == TAG_TYPE_LOCAL)
@@ -630,7 +638,10 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
{
case TAG_LOCAL_USAGE:
if (usages_top == sizeof(usages))
+ {
ERR("More than 256 individual usages defined\n");
+ return -1;
+ }
else
{
usages[usages_top++] = getValue(bSize, itemVal, FALSE);
@@ -674,10 +685,14 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
break;
default:
ERR("Unknown (bTag: 0x%x, bType: 0x%x)\n", bTag, bType);
+ return -1;
}
}
else
+ {
ERR("Unknown (bTag: 0x%x, bType: 0x%x)\n", bTag, bType);
+ return -1;
+ }
i += bSize;
}
@@ -927,7 +942,7 @@ static WINE_HIDP_PREPARSED_DATA* build_PreparseData(struct collection *base_coll
nodes_offset = size;
size += node_count * sizeof(WINE_HID_LINK_COLLECTION_NODE);
- data = calloc(1, size);
+ if (!(data = calloc(1, size))) return NULL;
data->magic = HID_MAGIC;
data->dwSize = size;
data->caps.Usage = base_collection->caps.NotRange.Usage;
@@ -982,14 +997,18 @@ WINE_HIDP_PREPARSED_DATA* ParseDescriptor(BYTE *descriptor, unsigned int length)
list_init(&caps_stack);
- base = calloc(1, sizeof(*base));
+ if (!(base = calloc(1, sizeof(*base)))) return NULL;
base->index = 1;
list_init(&base->features);
list_init(&base->collections);
memset(&caps, 0, sizeof(caps));
cidx = 0;
- parse_descriptor(descriptor, 0, length, &feature_count, &cidx, base, &caps, &caps_stack);
+ if (parse_descriptor(descriptor, 0, length, &feature_count, &cidx, base, &caps, &caps_stack) < 0)
+ {
+ free_collection(base);
+ return NULL;
+ }
debug_collection(base);
@@ -1004,8 +1023,8 @@ WINE_HIDP_PREPARSED_DATA* ParseDescriptor(BYTE *descriptor, unsigned int length)
}
}
- data = build_PreparseData(base, cidx);
- debug_print_preparsed(data);
+ if ((data = build_PreparseData(base, cidx)))
+ debug_print_preparsed(data);
free_collection(base);
return data;
--
2.31.0
More information about the wine-devel
mailing list