Devolutions / Devolutions/IronRDP
clearcodec: RLEX regions with a single palette entry are parsed without their packed byte
- Dominant language
- Rust
- Stars
- 3.2k
- Forks
- 275
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 189
Description
## Summary
`ironrdp_pdu::codecs::clearcodec::decode_rlex` treats a one-entry palette as a special case (`stop_index_bits = 0`, `decode_single_palette_segments`): each segment is read as a bare run length, without the packed `suiteDepth | stopIndex` byte. Per MS-RDPEGFX 2.2.4.6.2.2 the packed byte is always present; the bit width of `stopIndex` is `floor(log2(paletteCount - 1)) + 1`, and for `paletteCount == 1` FreeRDP's `CLEAR_LOG2_FLOOR[0]` yields 0, i.e. **one bit** for `stopIndex` and seven for `suiteDepth` (`clear_decompress_subcode_rlex` in `libfreerdp/codec/clear.c`).
As a result every run length is read one byte off, and the decoder fails with `invalid rlex: suite exceeds region pixel count`.
## Real-world trigger
Windows Server 2025 encodes the solid corners of its taskbar as one-colour RLEX regions (14×64, 64×46, 50×64; 35-byte ClearCodec PDUs). Against such a server every one of those regions is rejected: nine refusals in a twenty-second session, seen with the EGFX journal of the avash client.
## Fix
Give `stopIndex` one bit when `palette_count <= 1` and go through the ordinary segment parser; drop the special path. PR follows, with a test that decodes a 14×64 one-colour region (run of 895 on a 16-bit length plus a suite of one).
The same fix has been shipped in avash's vendored copy of `ironrdp-pdu` (https://github.com/AdrienAvalon/avash/blob/main/rdp-sidecar/vendor/README.md, section "RLEX à une seule couleur").
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at ironrdp_pdu::codecs::clearcodec::decode_rlex and compare its single-entry palette handling with MS-RDPEGFX 2.2.4.6.2.2 and the cited FreeRDP routine. Add or run coverage for a 14×64 one-colour region, and consider the issue complete when its packed segment decodes with the expected 895 run and suite of one without the pixel-count error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100