Skip to content

fix(graphics): decode Progressive SRL refinements - #1696

Merged
Marc-André Moreau (mamoreau-devolutions) merged 2 commits into
masterfrom
copilot/progressive-srl-refinements
Aug 18, 2026
Merged

fix(graphics): decode Progressive SRL refinements#1696
Marc-André Moreau (mamoreau-devolutions) merged 2 commits into
masterfrom
copilot/progressive-srl-refinements

Conversation

@mamoreau-devolutions

@mamoreau-devolutions Marc-André Moreau (mamoreau-devolutions) commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Preserve SRL and raw-bit state across Progressive DWT bands.

Reject malformed SRL refinement streams without decoding invented zero data or partially updating tiles.

Preserve SRL and raw-bit state across Progressive DWT bands.

Reject malformed SRL refinement streams instead of decoding invented zero data.
Copilot AI balanced review requested due to automatic review settings August 18, 2026 13:04
@github-actions github-actions Bot added breaking-change Includes a breaking change, and requires special scrutiny at the boundaries kind/protocol Affects RDP or related protocol behavior maintainer-required Maintainer review or intervention is required risk/high Substantial core public API impact, or fail-closed triage; needs maintainer-level scrutiny scope/core Touches the core architectural tier size/L Size: up to 899 counted lines and 20 files; exceeds M in either measure labels Aug 18, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes Progressive RemoteFX refinement decoding by preserving SRL and raw-bit state across DWT bands.

Changes:

  • Adds stateful, fallible SRL encoding and decoding.
  • Preserves component streams across bands and propagates SRL errors.
  • Adds malformed-stream and cross-band tests.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
crates/ironrdp-graphics/src/srl.rs Implements stateful SRL codecs and validation.
crates/ironrdp-graphics/src/progressive.rs Integrates stateful streams into progressive upgrades.

Comment thread crates/ironrdp-graphics/src/progressive.rs
@github-actions github-actions Bot added ai-reviewed/1 One automated review completed and removed maintainer-required Maintainer review or intervention is required labels Aug 18, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Rewrite of the Progressive codec's SRL entropy coder and TILE_UPGRADE pass into stateful SrlDecoder/SrlEncoder carrying KP and zero-run state across DWT bands, plus fixes to raw-bit continuity, Sign=0 coefficient accumulation, and rejection of malformed/truncated SRL streams via a new SrlError. I independently traced the bit-level logic against the MS-RDPEGFX worked examples cited in the protocol handoff and confirmed each mapped change behaves as claimed; encoder and decoder are symmetric, and has_srl_values gating matches on both sides. The Result-returning signature changes have no other call sites in the workspace beyond the two files reviewed and a single ?-propagating caller, consistent with existing RlgrError handling in this module. No blocking defects found; two minor non-blocking observations below.

Protocol analysis: accepted — Manually re-derived bit sequences for the cited MS-RDPEGFX examples (KP=8 init/escape decoding, unterminated max-magnitude unary decode, cross-band zero-run/KP continuity, cross-band raw-bit continuity, Sign=0 accumulation, LL3 always-raw exclusion) against the code and its own test vectors; all seven change_mappings hold up as conforming. The MAX_ZERO_RUN=4096 potential_discrepancy is accurate but not a functional defect: it is looser than the true eligible-coefficient bound (4096 minus 64 LL3), so it cannot reject conformant data. No additional material protocol concerns found.

Comment thread crates/ironrdp-graphics/src/progressive.rs
Comment thread crates/ironrdp-graphics/src/srl.rs
Stage component refinements before committing an upgrade pass.

Reuse zero counts across SRL decoding bands.
@github-actions github-actions Bot added maintainer-required Maintainer review or intervention is required ai-reviewed/2 Final automated review completed and removed ai-reviewed/1 One automated review completed labels Aug 18, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Well-scoped, protocol-conformant fix. It rewrites the SRL codec as stateful decoder/encoder types that persist zero-run/KP state and bit position across DWT bands, fixes zero-DAS accumulation to add rather than overwrite (matching MS-RDPEGFX 3.3.8.2.1.2), excludes LL3 from SRL entirely, and makes malformed/truncated SRL streams a hard error that leaves TileState untouched (staged local copies committed only after all three components decode). Tests trace the algorithm against the spec's worked examples and cover the new cross-band and rollback behavior. One residual inconsistency (raw-bit truncation still silently zero-fills while SRL truncation now errors) is real but pre-existing/out of scope for this fix.

Protocol analysis: accepted — Independently traced the shared SrlDecoder/RawBitReader across bands, the accumulate-vs-overwrite fix, the new !is_ll3 guard excluding LL3 from SRL, and TileState::decode_upgrade's stage-then-commit rollback, plus the zero-run/unary state machines, against the cited MS-RDPEGFX sections. All match the handoff's conformance calls; the tests exercise exactly the scenarios it flagged as valuable. The flagged RawBitReader-vs-SrlDecoder truncation-handling discrepancy is confirmed still present, but RawBitReader is untouched by this diff so it is reasonably follow-up, not a defect in this change.

  1. question / low — crates/ironrdp-graphics/src/srl.rs
    SrlDecoder::new rejects a stream whose trailing byte is absent or non-zero with MissingTerminator, but MS-RDPEGFX 3.1.8.1.5 states only that a conformant encoder always appends the zero terminator, without explicitly mandating decoder rejection of its absence. Given this crate's public API and that ironrdp is a client decoding server-sent data, was this intentionally chosen as defensive hardening rather than a spec-mandated decoder requirement? The rejects_missing_terminator test only documents the chosen behavior, not the rationale.

Comment thread crates/ironrdp-graphics/src/progressive.rs
@mamoreau-devolutions
Marc-André Moreau (mamoreau-devolutions) merged commit 7824bc7 into master Aug 18, 2026
44 of 61 checks passed
@mamoreau-devolutions
Marc-André Moreau (mamoreau-devolutions) deleted the copilot/progressive-srl-refinements branch August 18, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-reviewed/2 Final automated review completed breaking-change Includes a breaking change, and requires special scrutiny at the boundaries kind/protocol Affects RDP or related protocol behavior maintainer-required Maintainer review or intervention is required risk/high Substantial core public API impact, or fail-closed triage; needs maintainer-level scrutiny scope/core Touches the core architectural tier size/L Size: up to 899 counted lines and 20 files; exceeds M in either measure

Development

Successfully merging this pull request may close these issues.

2 participants