feat(egfx): cascade Arbitrary derives across ironrdp-egfx public PDU types#1334
Merged
Benoît Cortier (CBenoit) merged 1 commit intoJun 1, 2026
Conversation
…types Extends the Arbitrary cascade from PR Devolutions#1272 (ironrdp-pdu) and PR Devolutions#1284 (extension to pdu types in ironrdp-pdu's egfx-related modules) to the ironrdp-egfx crate's own public type surface. Adds the arbitrary feature to ironrdp-egfx and adds the standard #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] gate to every public PDU type in crates/ironrdp-egfx/src/pdu/: - common.rs: Point, Color, PixelFormat - avc.rs: Avc420BitmapStream, Avc444BitmapStream, Avc420Region - cmd.rs: GfxPdu plus all 23 variant types, RawCapabilitySet, CapabilitySet, CapabilityVersion, Codec1Type, Codec2Type, QueueDepth, CacheEntryMetadata, and the six CapabilitiesV*Flags bitflags structs. Three types use a manual Arbitrary impl rather than the derive because their fields have implicit wire-bit-width constraints the derive cannot express. derive(Arbitrary) on these types generates values in the full underlying type range, which the encoder then panics on when packing into the narrower wire range. Manual impls mask each field to its spec-defined width: - Timestamp (cmd.rs): milliseconds and hours into 10 bits each, seconds and minutes into 6 bits each. The encoder packs all four into a single u32 via set_bits. - QuantQuality (avc.rs): quantization_parameter into 6 bits. Encoder packs into a u8 via set_bits(0..6). - Encoding bitflag (avc.rs): masked to 2 bits. The bitflag's `const _ = !0` clause otherwise accepts any u8 value, but the encoder for Avc444BitmapStream packs encoding.bits() into bits 30..32 of the stream-info field. The arbitrary feature cascades through ironrdp-pdu/arbitrary so types in egfx's variant payloads (ExclusiveRectangle, etc.) pick up their existing Arbitrary impls. bitflags/arbitrary is activated so the CapabilitiesV*Flags bitflag types get Arbitrary via the bitflags crate's own derive support. Adds the ironrdp-egfx/arbitrary case to the xtask feature matrix (xtask/src/features.rs), mirroring the ironrdp-pdu/arbitrary entry, so CI verifies the feature builds cleanly. Default build (no arbitrary feature) is unchanged. Existing tests pass. cargo xtask check features --case ironrdp-egfx/arbitrary clean. This is the prerequisite cascade for the egfx_multi_frame fuzz target (target 5 under Devolutions#1316), which will use Arbitrary-derived Vec<GfxPdu> to drive a single decoder + surface-cache pair across each fuzz iteration. The target itself follows in a separate PR. Per the Devolutions#1122 guidance ("either implement Arbitrary manually and reject invalid values, or generate a raw value and then sanitize it"), the three manual impls here follow the sanitize-via-mask shape so generated values always round-trip through Encode. Refs Devolutions#1316.
42f67d7 to
92ebf1e
Compare
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.
Summary
Arbitrarycascade from PR feat(pdu): add arbitrary feature for structure-aware fuzzing #1272 (ironrdp-pdu) and PR refactor(egfx)!: mark consumer-facing types as#[non_exhaustive]for pre-publish API stability #1284 (extension to pdu types in egfx-adjacent modules) to theironrdp-egfxcrate's own public type surface.arbitraryfeature toironrdp-egfx/Cargo.toml, cascading throughironrdp-pdu/arbitraryandbitflags/arbitraryso variant payload types and bitflag types pick up theirArbitraryimpls automatically.#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]to every public PDU type incrates/ironrdp-egfx/src/pdu/:common.rs:Point,Color,PixelFormatavc.rs:QuantQuality,Avc420BitmapStream<'a>,Avc444BitmapStream<'a>,Avc420Region,Encoding(bitflags)cmd.rs:GfxPduplus all 23 variant types,RawCapabilitySet,CapabilitySet,CapabilityVersion,Codec1Type,Codec2Type,Timestamp,QueueDepth,CacheEntryMetadata, and the sixCapabilitiesV*Flagsbitflag structs.ironrdp-egfx/arbitrarycase to the xtask feature matrix (xtask/src/features.rs), mirroring the existingironrdp-pdu/arbitraryentry so CI verifies the feature builds cleanly.Validation
cargo xtask ciclean locally on1.89.0: fmt, lints, tests, typos, locks all green.cargo xtask check features --case ironrdp-egfx/arbitraryclean.ironrdp-egfxunit tests continue to pass.arbitraryfeature) unchanged: no new dependencies pulled, no behavior change.Notes
egfx_multi_framefuzz target (target 5 under egfx: extend fuzz coverage to OpenH264-wrapper, ZGFX, multi-frame state, and encoder round-trip #1316), which will useArbitrary-derivedVec<GfxPdu>to drive a single decoder + surface-cache pair across each fuzz iteration. The target itself follows in a separate PR.#[cfg_attr(feature = "arbitrary", ...)], and the feature isoptional = truein Cargo.toml. Default consumers see no change.bitflags/arbitraryactivation in the feature cascade so the bitflags crate's ownArbitrarysupport reaches theCapabilitiesV*FlagsandEncodingtypes.GfxPduvariant types all use owned types (Vec<u8>for bitmap payloads, fixed-width integers, ownedExclusiveRectanglefrom ironrdp-pdu); none requires a manualArbitraryimpl. Lifetime-parameterized types (Avc420BitmapStream<'a>,Avc444BitmapStream<'a>) getArbitrary<'a>impls automatically per the standard derive behavior.Refs #1316.