Skip to content

refactor(pdu): make the CapabilitySet encoder exhaustive#1328

Open
Greg Lamberson (glamberson) wants to merge 1 commit into
Devolutions:masterfrom
lamco-admin:refactor/capability-sets-exhaustive-encoder
Open

refactor(pdu): make the CapabilitySet encoder exhaustive#1328
Greg Lamberson (glamberson) wants to merge 1 commit into
Devolutions:masterfrom
lamco-admin:refactor/capability-sets-exhaustive-encoder

Conversation

@glamberson

@glamberson Greg Lamberson (glamberson) commented May 27, 2026

Copy link
Copy Markdown
Contributor

Part of the unreachable!() / panic!() audit pass on #1314, scoped to crates/ironrdp-pdu/src/rdp/capability_sets/.

mod.rs (CapabilitySet::Encode::encode raw-buffer fallback): the inner _ => unreachable!() catch-all is replaced with an explicit enumeration of the 17 structured CapabilitySet variants already handled by the outer match. Adding a new variant to CapabilitySet is now a compile error here until it is routed in this Encode impl. The arm body stays unreachable!() (genuinely unreachable under the current outer-match structure). PR #1313 (BitmapCacheV3 encoder unreachable!() reached on decoder-accepted input) is why a runtime catch-all is the wrong shape here.

bitmap_codecs/mod.rs (CodecProperty decode for GUID_REMOTEFX | GUID_IMAGE_REMOTEFX): keeps its match guid { ... _ => unreachable!() } structure per review. guid is already validated by the outer arm, so the _ branch is a redundant correctness check that fires under tests and fuzzing if a future change breaks the invariant. The only change is an inline message documenting that invariant.

Both sites are class (a) (provably unreachable in current code), confirmed by pdu_round_trip (#1291) and message_decoding_invariants (#1320) exercising CapabilitySet and ShareControlHeader for millions of iterations post-#1313 with no panics.

Refs #1314.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR is part of the ironrdp-pdu audit work (issue #1314) to remove runtime unreachable!() catch-alls in capability-set code paths and replace them with structures that either become compile-time exhaustive (for enum variants) or remove provably-dead branches (for GUID-discriminated decoding). The goal is to turn future regressions from runtime panics into compile errors or eliminate unreachable branches entirely.

Changes:

  • In CapabilitySet::encode, replaced an inner _ => unreachable!() with an explicit list of the structured CapabilitySet variants, so adding a new enum variant forces this site to be updated at compile time.
  • In Codec decoding for GUID_REMOTEFX | GUID_IMAGE_REMOTEFX, removed a dead nested match ... _ => unreachable!() and replaced it with an if/else based on the already-constrained guid.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
crates/ironrdp-pdu/src/rdp/capability_sets/mod.rs Makes the raw-buffer fallback’s inner match exhaustive w.r.t. CapabilitySet variants, preventing future missing-variant bugs from compiling.
crates/ironrdp-pdu/src/rdp/capability_sets/bitmap_codecs/mod.rs Removes an unreachable nested match arm in RemoteFX property decoding by leveraging the outer match’s constraint on guid.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

The inner match in `CapabilitySet::Encode::encode`'s raw-buffer fallback
(`mod.rs:448`) used a `_ => unreachable!()` catch-all. Replace it with an
explicit enumeration of the 17 structured `CapabilitySet` variants already
handled by the outer match's specific arms, so adding a new variant to
`CapabilitySet` is a compile error here until the variant is routed in this
`Encode` impl. The arm body stays `unreachable!()` because it is genuinely
unreachable under the current outer-match structure. PR Devolutions#1313 (BitmapCacheV3
encoder `unreachable!()` reached on decoder-accepted input) demonstrated why
a runtime catch-all is the wrong shape for this match.

The nested `match guid { ... _ => unreachable!() }` in `CodecProperty` decode
for `GUID_REMOTEFX | GUID_IMAGE_REMOTEFX` (`bitmap_codecs/mod.rs`) keeps its
structure. Per review, `unreachable!()` is the right tool there: `guid` is
already validated by the outer arm, so the `_` branch is a redundant
correctness check that fires under tests and fuzzing if a future change breaks
the invariant. The only change is a message documenting that invariant inline.

This is part of the audit pass on issue Devolutions#1314. Both sites are class (a)
(provably unreachable in current code), confirmed by `pdu_round_trip` (Devolutions#1291)
and `message_decoding_invariants` (Devolutions#1320) exercising `CapabilitySet` and
`ShareControlHeader` for millions of iterations post-Devolutions#1313 with no panics.

Refs Devolutions#1314.
@glamberson Greg Lamberson (glamberson) force-pushed the refactor/capability-sets-exhaustive-encoder branch from ba67cc7 to 6b00318 Compare June 8, 2026 13:07
@glamberson Greg Lamberson (glamberson) changed the title refactor(pdu): replace unreachable!() in capability_sets/ with exhaustive matching refactor(pdu): make the CapabilitySet encoder exhaustive Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants