[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