Skip to content

Validate malformed input packets before decoding - #2024

Open
cmuellner wants to merge 5 commits into
mcallegari:masterfrom
cmuellner:pr-1955-fixes-p1
Open

Validate malformed input packets before decoding#2024
cmuellner wants to merge 5 commits into
mcallegari:masterfrom
cmuellner:pr-1955-fixes-p1

Conversation

@cmuellner

Copy link
Copy Markdown
Contributor

Description

Summary of Changes:

This PR fixes malformed-input reliability issues found while reviewing
stale PR #1955 and adjacent parser code.

The affected parsers now reject short or inconsistent input before
reading fixed fields or payload bytes. Well-formed input is handled as
before.

Commit Guide

Commit Origin Reproduction / coverage
Script: reject fixtures outside universe list Reported in PR #1955 Added a regression test in script_test for a fixture whose universe is absent from the runtime universe list.
Art-Net: reject packets with truncated fields Reported in PR #1955 Extended artnet_test with short ArtPollReply, ArtDMX and ArtTOD packets.
E1.31: validate DMX property value count Reported in PR #1955 Added e131packetizer_test coverage for missing start code, zero count, truncated payload and a valid packet.
OSC: reject truncated messages and bundle sizes Reported in PR #1955 Added oscpacketizer_test coverage for unterminated type tags, truncated string arguments, short bundle size fields and a valid bundle.
RDM: validate response length before decoding Derived while validating PR #1955 Extended artnet_test with short RDM headers, oversized or truncated PDL values, too-short PID payloads, and valid ACK responses.
DMX USB: validate Enttec input payload offsets Derived while validating PR #1955 No automated regression test exists for this device input path; a reviewer with compatible hardware can smoke-test normal DMX and MIDI input for regressions.

Testing

Automated Coverage:

The parser paths with in-tree harnesses are covered by:

  • script_test
  • artnet_test
  • e131packetizer_test
  • oscpacketizer_test

Result:

The added and extended tests pass locally.

Manual Testing Gaps

The Enttec DMX USB Pro input-path change is not covered by an
automated regression test because the current tree does not provide a
device-level test harness for that plugin.

A reviewer with compatible hardware can help confirm there is no
behavioral regression by connecting the device, enabling the DMX USB
plugin, and verifying that normal DMX input and MIDI input still work.

Additional Notes

The fixes are split into one commit per issue so individual parser
changes remain easy to review and bisect.

Each commit body contains the full rationale and reproduction details.

Checklist

  • I have read and followed the QLC+ Coding Guidelines.
  • My code adheres to the project's coding style, including:
    • Placing opening braces { on a new line for functions and class definitions.
    • Consistent use of spaces and indentation.
  • I have tested my changes on the following platforms:
    • Linux
    • Windows
    • macOS
  • I have added or updated documentation as necessary.

@coveralls

coveralls commented May 18, 2026

Copy link
Copy Markdown

Coverage Status

coverage: 35.895% (+0.6%) from 35.286% — cmuellner:pr-1955-fixes-p1 into mcallegari:master

@cmuellner

Copy link
Copy Markdown
Contributor Author

Testing update for this PR:

I re-tested the covered cases against both current master and this feature branch.

For the baseline check, I applied only the test/CMake changes to master and ran the new regression tests there first. The tests reproduce the reported failure modes on master:

  • script_test: crashes with SIGSEGV in setFixtureRejectsMissingUniverse
  • artnet_test: 5 failures for malformed ArtNet/RDM packet handling
  • e131packetizer_test: 5 failures for malformed E1.31 packet handling
  • oscpacketizer_test: 3 failures for malformed OSC packet handling

Then I ran the same tests on this PR branch. Results:

  • script_test: 5 passed, 0 failed
  • artnet_test: 12 passed, 0 failed
  • e131packetizer_test: 8 passed, 0 failed
  • oscpacketizer_test: 7 passed, 0 failed

So the automated regressions covered by this PR are verified: the tests fail or crash on master with only the tests applied, and pass on the PR branch.

The remaining Enttec DMX USB Pro malformed-input path is still not covered by an automated test in this verification pass.

cmuellner added 5 commits June 8, 2026 00:02
Origin: reported in PR mcallegari#1955.

The regression test creates a fixture on universe 1, then calls
`setfixture` with a runtime universe list that only contains universe
0. Before this fix, `handleSetFixture()` indexed `universes[1]` and
could read past the list.

Reject the command before requesting a fader when the fixture universe
is not present in the runtime universe list. This keeps malformed or
inconsistent projects from crashing script playback.

Added a regression test in `script_test` for a fixture whose universe
is missing from the runtime universe list.

Signed-off-by: Christoph Müllner <christophm30@gmail.com>
Origin: reported in PR mcallegari#1955.

The regression test covers protocol inputs rather than GUI steps: a
186-byte ArtPollReply, a short ArtDMX packet, an ArtDMX packet whose
length field exceeds the datagram, and a TOD packet with `uidCount` 1
but no UID bytes. These inputs previously reached fixed-offset reads or
accepted an incomplete UID list.

Validate the minimum ArtPollReply size, the ArtDMX fixed header and
advertised payload length, and the TOD UID list length before decoding.

Extended `artnet_test` to cover short ArtPollReply, short ArtDMX,
truncated ArtDMX payload, and truncated TOD UID list packets.

Signed-off-by: Christoph Müllner <christophm30@gmail.com>
Origin: reported in PR mcallegari#1955.

The regression test covers protocol inputs rather than GUI steps: a
125-byte packet missing the DMX start code, a zero property value count,
and a packet whose count exceeds the remaining datagram. Before this
fix, `checkPacket()` accepted the missing-start-code packet and
`fillDMXdata()` could read byte 125 or underflow `length - 1`.

Require the start-code byte before accepting an E1.31 DMX packet, then
reject zero, oversized, or truncated property value counts before
copying DMX slots.

Added `e131packetizer_test` to cover a missing start code, zero
property value count, truncated payload, and a valid packet.

Signed-off-by: Christoph Müllner <christophm30@gmail.com>
Origin: reported in PR mcallegari#1955.

The regression test covers protocol inputs rather than GUI steps: an
OSC message whose type-tag list has no NUL terminator, a message whose
string argument is missing its NUL terminator, and a bundle with a valid
first message followed by a trailing 3-byte message-size field. Before
this fix, parseMessage() could scan past the message buffer or accept a
truncated argument, and the bundle parser could read bufPos + 3 past the
packet.

Stop type-tag and string-argument scanning at the buffer end. Reject
fixed-size arguments whose bytes are not fully present, and require four
bytes before reading each bundled message size.

Added oscpacketizer_test to cover unterminated type tags, truncated
string arguments, short bundle size fields, and a valid bundled
message.

Signed-off-by: Christoph Müllner <christophm30@gmail.com>
Origin: derived while validating PR mcallegari#1955.

The regression test uses protocol inputs in artnet_test: a one-byte
RDM start-code packet, a 22-byte fixed header, a packet whose PDL claims
21 bytes without carrying that payload, and a DEVICE_INFO response whose
valid checksum covers a too-short PID payload. Before this fix,
parsePacket() could read the sub-start code, fixed response fields, or
PID-specific payload beyond the reply buffer or beyond the declared
PDL.

Validate the fixed response header before decoding fields, then require
PDL bytes plus the checksum before entering PID-specific parsing. Reject
PID payloads that are too short for fixed-field decoders, and decode the
19-byte DEVICE_INFO sensor-count field at its protocol offset.

Extended artnet_test to cover short RDM headers, truncated PDL payloads,
too-short PID payloads, and valid RDM packets.

Signed-off-by: Christoph Müllner <christophm30@gmail.com>
@cmuellner

Copy link
Copy Markdown
Contributor Author

I removed the Enttec DMX USB Pro input-path change from this PR. That path needs validation with compatible hardware, which I do not have, so it should not be part of this PR.

The remaining changes are limited to parser/script paths covered by automated regression tests.

With this, I believe that this PR becomes a set of non-controversial fixes with tested fixes.

I also rebased the branch onto current master, so the commit hashes changed.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants