Devolutions / Devolutions/IronRDP

clearcodec: RLEX regions with a single palette entry are parsed without their packed byte

Open Beginner friendly
#1,902 0 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.