Skip to content

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

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").

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions