hid: fix bug in report parsing when reports are not declared contiguously - #936
Merged
williampMSFT merged 1 commit intoAug 5, 2026
Conversation
williampMSFT
marked this pull request as ready for review
August 5, 2026 20:49
williampMSFT
requested review from
RobertZ2011,
felipebalbi,
jerrysxie and
tullom
and
a lite review from Copilot
August 5, 2026 20:49
Contributor
There was a problem hiding this comment.
Pull request overview
Summary of changes
This PR fixes a correctness bug in HID report-descriptor parsing where report fields for the same Report ID can appear in multiple non-contiguous regions of the descriptor. Instead of treating “switching report IDs” as ending the current report and only tracking a running max, the parser now accumulates bit sizes per Report ID across the entire descriptor. This aligns the implementation with legal HID descriptor patterns where a report ID can be revisited and extended later. New unit tests cover both non-contiguous Report ID re-entry and Push/Pop restoring a prior report ID.
Changes:
- Track accumulated
Input/Output/Featurebit counts per Report ID while parsing, then compute the max at the end. - Remove the previous “flush on report-id switch / pop-to-different-id” logic that incorrectly split reports.
- Add tests for non-contiguous Report ID declarations and for Report ID restoration via
Pop.
Step-by-step review guide
-
Parsing logic change: accumulate per Report ID
- The constructor now maintains a
reportstable keyed bystate.report_id, and adds each Main item’s computedbitsto the appropriate entry. - This matters because HID descriptors can legally interleave report IDs; the final report size must reflect the sum of all fields for that ID, regardless of contiguity.
- The constructor now maintains a
-
Push/Pop semantics
Popnow simply restores the priorGlobalItemStatewithout forcing a “report boundary.”- This is important because Push/Pop can restore a prior report ID and continue adding fields to the same report, which should be accumulated rather than treated as a new report.
-
Final max computation
- After parsing, the code iterates across all tracked reports and computes the maximum
input/output/featurepayload sizes. - This preserves the intended API contract:
max_report_sizes()returns the maximum payload size across all report IDs (excluding the report ID byte), now with correct aggregation.
- After parsing, the code iterates across all tracked reports and computes the maximum
Potential issues
No issues found.
| # | Severity | File | Description | Code |
|---|---|---|---|---|
| — | — | — | No issues found. | — |
kurtjd
approved these changes
Aug 5, 2026
felipebalbi
reviewed
Aug 5, 2026
jerrysxie
approved these changes
Aug 5, 2026
RobertZ2011
approved these changes
Aug 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#933 had a bug: it was not correctly handling the case where a report ID gets 'revisited', but it turns out it's legal to go back to an earlier report ID and keep adding to it, e.g.
means that report ID 1 is a 4-byte report. This changes our parsing logic to account for this; we have to track each individual report instead of just the largest observed so far.