summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2026-03-09 11:12:16 +0700
committerGitHub <[email protected]>2026-03-09 11:12:16 +0700
commit66d67026f29101b76d7837646bd291b95d69f4bb (patch)
tree1640c8632b80069d27e169845c2a3e6450025626
parentda307fa85b4002c875284bb82d7db1ca1bc7347d (diff)
parent3e22de0a4782d6062959aec27e5304f1b4d4a557 (diff)
Merge pull request #3532 from YixingShen/master
_open_vc_itf parsing error when vc->std.bNumEndpoints != 0
-rw-r--r--src/class/video/video_device.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c
index b2375def9..d1c699940 100644
--- a/src/class/video/video_device.c
+++ b/src/class/video/video_device.c
@@ -70,6 +70,13 @@ typedef struct TU_ATTR_PACKED {
uint8_t bEntityId;
} tusb_desc_cs_video_entity_itf_t;
+typedef struct TU_ATTR_PACKED {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bDescriptorSubtype;
+ uint16_t wMaxTransferSize;
+} tusb_desc_cs_video_vc_ep_t;
+
typedef union {
struct TU_ATTR_PACKED {
uint8_t bLength;
@@ -392,7 +399,13 @@ static void const* _find_desc_ep(void const *beg, void const *end)
static inline void const* _end_of_control_descriptor(void const *desc)
{
tusb_desc_vc_itf_t const *vc = (tusb_desc_vc_itf_t const *)desc;
- return ((uint8_t const*) desc) + vc->std.bLength + tu_le16toh(vc->ctl.wTotalLength);
+ uint8_t const *end = (uint8_t const*)desc + vc->std.bLength
+ + tu_le16toh(vc->ctl.wTotalLength);
+ if (vc->std.bNumEndpoints) {
+ end += sizeof(tusb_desc_endpoint_t); // standard EP descriptor
+ end += 5; // class-specific EP descriptor (fixed 5 bytes per UVC spec)
+ }
+ return end;
}
/** Find the first entity descriptor with the entity ID
@@ -740,6 +753,9 @@ static bool _close_vc_itf(uint8_t rhport, videod_interface_t *self)
/* The end of the video control interface descriptor. */
void const *end = _end_of_control_descriptor(vc);
if (vc->std.bNumEndpoints != 0) {
+ /* Extend end to cover the standard endpoint and class-specific endpoint descriptors
+ * that follow wTotalLength */
+ end = (uint8_t const*)end + sizeof(tusb_desc_endpoint_t) + sizeof(tusb_desc_cs_video_vc_ep_t);
/* Find the notification endpoint descriptor. */
cur = _find_desc(cur, end, TUSB_DESC_ENDPOINT);
TU_ASSERT(cur < end);
@@ -780,6 +796,9 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t
if (vc->std.bNumEndpoints != 0) {
/* Support for 1 endpoint only. */
TU_VERIFY(1 == vc->std.bNumEndpoints);
+ /* Extend end to cover the standard endpoint and class-specific endpoint descriptors
+ * that follow wTotalLength */
+ end = (uint8_t const*)end + sizeof(tusb_desc_endpoint_t) + sizeof(tusb_desc_cs_video_vc_ep_t);
/* Find the notification endpoint descriptor. */
cur = _find_desc(cur, end, TUSB_DESC_ENDPOINT);
TU_VERIFY(cur < end);