Skip to content

Commit 4c53018

Browse files
authored
fix(connector)!: remove arbitrary feature (#1273)
The connector types are unlikely to benefit from random value generation for fuzzing purposes; a more targeted approach would be preferable if the connector is fuzzed in the future. We’ll reevaluate later.
1 parent af11df1 commit 4c53018

7 files changed

Lines changed: 7 additions & 55 deletions

File tree

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ironrdp-connector/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ test = false
1818

1919
[features]
2020
default = []
21-
arbitrary = ["dep:arbitrary", "ironrdp-pdu/arbitrary"]
2221
qoi = ["ironrdp-pdu/qoi"]
2322
qoiz = ["ironrdp-pdu/qoiz"]
2423

@@ -27,7 +26,6 @@ ironrdp-svc = { path = "../ironrdp-svc", version = "0.6" } # public
2726
ironrdp-core = { path = "../ironrdp-core", version = "0.1" } # public
2827
ironrdp-error = { path = "../ironrdp-error", version = "0.1" } # public
2928
ironrdp-pdu = { path = "../ironrdp-pdu", version = "0.7", features = ["std"] } # public
30-
arbitrary = { version = "1", features = ["derive"], optional = true } # public
3129
sspi = { version = "0.19", features = ["scard"] }
3230
url = "2.5" # public
3331
rand = { version = "0.9", features = ["std"] } # TODO: dependency injection?

crates/ironrdp-connector/src/channel_connection.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use crate::{
1212

1313
#[derive(Default, Debug)]
1414
#[non_exhaustive]
15-
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1615
pub enum ChannelConnectionState {
1716
#[default]
1817
Consumed,
@@ -56,7 +55,6 @@ impl State for ChannelConnectionState {
5655
}
5756

5857
#[derive(Debug)]
59-
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
6058
pub struct ChannelConnectionSequence {
6159
pub state: ChannelConnectionState,
6260
pub channel_ids: Option<HashSet<u16>>,

crates/ironrdp-connector/src/connection_finalization.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use crate::{ConnectorResult, Sequence, State, Written, general_err, legacy, reas
1111

1212
#[derive(Default, Debug, Copy, Clone)]
1313
#[non_exhaustive]
14-
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1514
pub enum ConnectionFinalizationState {
1615
#[default]
1716
Consumed,
@@ -49,7 +48,6 @@ impl State for ConnectionFinalizationState {
4948
}
5049

5150
#[derive(Debug, Copy, Clone)]
52-
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
5351
pub struct ConnectionFinalizationSequence {
5452
pub state: ConnectionFinalizationState,
5553
pub io_channel_id: u16,

crates/ironrdp-connector/src/lib.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ pub use crate::license_exchange::LicenseCache;
3434

3535
/// Provides user-friendly error messages for RDP negotiation failures
3636
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
37-
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
3837
pub struct NegotiationFailure(ironrdp_pdu::nego::FailureCode);
3938

4039
impl NegotiationFailure {
@@ -83,22 +82,19 @@ impl fmt::Display for NegotiationFailure {
8382
}
8483

8584
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
86-
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
8785
pub struct DesktopSize {
8886
pub width: u16,
8987
pub height: u16,
9088
}
9189

9290
#[derive(Debug, Clone)]
93-
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
9491
pub struct BitmapConfig {
9592
pub lossy_compression: bool,
9693
pub color_depth: u32,
9794
pub codecs: BitmapCodecs,
9895
}
9996

10097
#[derive(Debug, Clone)]
101-
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
10298
pub struct SmartCardIdentity {
10399
/// DER-encoded X509 certificate
104100
pub certificate: Vec<u8>,
@@ -113,7 +109,6 @@ pub struct SmartCardIdentity {
113109
}
114110

115111
#[derive(Debug, Clone)]
116-
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
117112
pub enum Credentials {
118113
UsernamePassword {
119114
username: String,
@@ -142,7 +137,6 @@ impl Credentials {
142137
}
143138

144139
#[derive(Debug, Clone)]
145-
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
146140
pub struct Config {
147141
/// The initial desktop size to request
148142
pub desktop_size: DesktopSize,
@@ -236,11 +230,6 @@ pub struct Config {
236230
pub enable_audio_playback: bool,
237231
pub performance_flags: PerformanceFlags,
238232

239-
// `Arc<dyn LicenseCache>` cannot be generated by `arbitrary`. Skipped via
240-
// `arbitrary(default)` which yields `None`. License-cache-dependent paths
241-
// are not exercised under fuzz; a fuzz-mode `LicenseCache` impl is a
242-
// possible follow-up.
243-
#[cfg_attr(feature = "arbitrary", arbitrary(default))]
244233
pub license_cache: Option<Arc<dyn LicenseCache>>,
245234

246235
// For Timezone Redirection to sync the server's timezone with the client's.
@@ -304,7 +293,6 @@ impl State for () {
304293
}
305294

306295
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
307-
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
308296
pub enum Written {
309297
Nothing,
310298
Size(core::num::NonZeroUsize),
@@ -351,8 +339,6 @@ pub type ConnectorResult<T> = Result<T, ConnectorError>;
351339

352340
#[non_exhaustive]
353341
#[derive(Debug)]
354-
// ConnectorErrorKind carries foreign error types (sspi::Error, ironrdp_error::Error)
355-
// that do not implement Arbitrary, so this enum is intentionally not annotated.
356342
pub enum ConnectorErrorKind {
357343
Encode(ironrdp_core::EncodeError),
358344
Decode(ironrdp_core::DecodeError),

crates/ironrdp-connector/src/license_exchange.rs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use crate::{ConnectorResult, ConnectorResultExt as _, Sequence, State, Written,
1515

1616
#[derive(Default, Debug)]
1717
#[non_exhaustive]
18-
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1918
pub enum LicenseExchangeState {
2019
#[default]
2120
Consumed,
@@ -65,29 +64,6 @@ pub struct LicenseExchangeSequence {
6564
pub license_cache: Arc<dyn LicenseCache>,
6665
}
6766

68-
// `license_cache` is `Arc<dyn LicenseCache>` which cannot be derived. The hand-rolled impl
69-
// hardcodes `NoopLicenseCache`, so license-cache-dependent paths are not exercised under fuzz.
70-
// Reaching the license sequence is still useful coverage (MS-RDPELE is a historically
71-
// interesting target). A fuzz-mode `LicenseCache` impl is a possible follow-up.
72-
#[cfg(feature = "arbitrary")]
73-
impl<'a> arbitrary::Arbitrary<'a> for LicenseExchangeSequence {
74-
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
75-
Ok(Self {
76-
state: LicenseExchangeState::arbitrary(u)?,
77-
io_channel_id: u16::arbitrary(u)?,
78-
username: String::arbitrary(u)?,
79-
domain: Option::<String>::arbitrary(u)?,
80-
hardware_id: [
81-
u32::arbitrary(u)?,
82-
u32::arbitrary(u)?,
83-
u32::arbitrary(u)?,
84-
u32::arbitrary(u)?,
85-
],
86-
license_cache: Arc::new(NoopLicenseCache),
87-
})
88-
}
89-
}
90-
9167
// Use RefUnwindSafe so that types that embed LicenseCache remain UnwindSafe
9268
pub trait LicenseCache: Sync + Send + Debug + RefUnwindSafe {
9369
fn get_license(&self, license_info: LicenseInformation) -> ConnectorResult<Option<Vec<u8>>>;

fuzz/README.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ To verify the feature compiles cleanly for a single crate:
4646

4747
```shell
4848
cargo check -p ironrdp-pdu --features arbitrary
49-
cargo check -p ironrdp-connector --features arbitrary
5049
```
5150

5251
The feature is also compatible with the `no_std + alloc` build path:
@@ -57,15 +56,13 @@ cargo check -p ironrdp-pdu --no-default-features --features arbitrary,alloc
5756

5857
A handful of PDU types do not implement `Arbitrary`. They fall into two categories:
5958

60-
- **Types with non-derivable fields** (e.g., `Arc<dyn LicenseCache>`,
61-
`StaticChannelSet` keyed by `TypeId`). These are either skipped via
62-
`#[arbitrary(default)]` on the containing struct's field, or hand-rolled
63-
with a placeholder.
59+
- **Types with non-derivable fields** (e.g., `StaticChannelSet` keyed by `TypeId`).
60+
These are either skipped via `#[arbitrary(default)]` on the containing struct's
61+
field, or hand-rolled with a placeholder.
6462
- **Error types that are not part of the wire-protocol surface** (e.g.,
65-
`ServerLicenseError`, `ConnectorErrorKind`). Most error enums fall here:
66-
they are constructed locally rather than decoded from the wire, so the
67-
fuzzer has no reason to generate them. The exception is wire-protocol
68-
error PDUs such as `DisconnectProviderUltimatum` in `mcs.rs`, which do
69-
implement `Arbitrary` because they are decoded from the wire.
63+
`ServerLicenseError`). Most error enums fall here: they are constructed locally
64+
rather than decoded from the wire, so the fuzzer has no reason to generate them.
65+
The exception is wire-protocol error PDUs such as `DisconnectProviderUltimatum`
66+
in `mcs.rs`, which do implement `Arbitrary` because they are decoded from the wire.
7067

7168
Inline source comments mark each skip with the rationale.

0 commit comments

Comments
 (0)