Skip to content

Fix MQTT decoder size check after variable header replay#16787

Merged
chrisvest merged 4 commits into
netty:4.2from
daguimu:fix/mqtt-cve-signal-check-16776
May 20, 2026
Merged

Fix MQTT decoder size check after variable header replay#16787
chrisvest merged 4 commits into
netty:4.2from
daguimu:fix/mqtt-cve-signal-check-16776

Conversation

@daguimu

@daguimu daguimu commented May 11, 2026

Copy link
Copy Markdown
Contributor

Problem

The MQTT decoder can reject valid packets after the CVE-2026-44248 fix when several MQTT packets are present in the same cumulation buffer. If the current packet's variable header needs a replay, the decoder compares the total readable bytes in the buffer against maxBytesInMessage, so later packets can make the current in-limit packet look too large.

Root Cause

READ_VARIABLE_HEADER recorded buffer.readableBytes() before decoding the variable header. That value is the cumulation's total readable bytes, not the current MQTT packet's declared remaining length. When decodeVariableHeader throws Signal.REPLAY, the too-large decision must be based on bytesRemainingBeforeVariableHeader for the current packet.

Fix

  • Use bytesRemainingBeforeVariableHeader when deciding whether to swallow Signal.REPLAY and raise TooLongFrameException.
  • Continue replaying when the current packet is within maxBytesInMessage, even if the cumulation contains additional bytes for following packets.

Tests Added

Change Point Test
Variable-header replay uses the current packet size instead of total cumulation bytes for the too-long check testPublishMessageIncompleteVariableHeaderDoesNotUseCumulationSizeForTooLongCheck() verifies an incomplete in-limit PUBLISH variable header with extra cumulated PINGREQ packets does not emit an invalid message
Oversized current packets still fail during variable-header replay testPublishMessageIncompleteVariableHeaderStillFailsWhenCurrentPacketTooLarge() verifies an incomplete PUBLISH whose own remaining length exceeds maxBytesInMessage still emits a TooLongFrameException

Impact

This restores decoding for valid in-limit MQTT packets batched in the same buffer while preserving the CVE fix: packets whose declared remaining length exceeds maxBytesInMessage still fail with TooLongFrameException even if variable-header decoding requests replay.

Fixes #16776

@chrisvest chrisvest left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just one small comment, otherwise looks good.

int followingPingReqPackets = 3;
EmbeddedChannel channel = new EmbeddedChannel(new MqttDecoder(maxBytesInMessage));
ByteBuf byteBuf = ALLOCATOR.buffer();
byteBuf.writeByte(0x30);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

None of the other tests directly encode MQTT messages. Please add some comments describing what's going on, so one can read this without having the MQTT standard at hand.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Pushed 4a91a65 with byte-level annotations on both tests: every writeByte/writeShort now spells out the MQTT field it represents (PUBLISH fixed header, remaining-length Variable Byte Integer, topic-name length prefix, PINGREQ packets), and each test opens with a note on why the packets are hand-crafted rather than routed through MqttEncoder. PTAL.

@chrisvest chrisvest added this to the 4.2.14.Final milestone May 12, 2026
@chrisvest chrisvest added needs-cherry-pick-4.1 This PR should be cherry-picked to 4.1 once merged. needs-cherry-pick-5.0 This PR should be cherry-picked to 5.0 once merged. labels May 12, 2026
@chrisvest

Copy link
Copy Markdown
Member

@daguimu Please look at my review comment.

Address review feedback on netty#16787: explain each writeByte / writeShort with the MQTT field it represents (PUBLISH fixed header, remaining-length VBI, topic-name length prefix, PINGREQ packets) so the tests can be read without the MQTT spec at hand. Also add a header comment on each test noting why the packets are hand-crafted instead of using MqttEncoder (the bug under test requires malformed packets that the encoder will not produce). No behavior change.
@daguimu

daguimu commented May 15, 2026

Copy link
Copy Markdown
Contributor Author

@chrisvest Sorry for the delay — addressed your review comment in 4a91a65 (also responded in-thread). Each writeByte/writeShort in the two new tests now names the MQTT field it represents (fixed-header byte, remaining-length Variable Byte Integer, topic-name length prefix, PINGREQ packets), and each test opens with a short note explaining why the packets are hand-crafted rather than routed through MqttEncoder. PTAL when you have a moment.

@normanmaurer normanmaurer requested a review from chrisvest May 18, 2026 14:11
@jbertram

Copy link
Copy Markdown
Contributor

Is there any chance this could get merged and included in a new release ASAP? Anybody using the MQTT codec can't upgrade to the most recent release which means they can't get the latest security fixes.

@chrisvest chrisvest merged commit 72df658 into netty:4.2 May 20, 2026
19 checks passed
@netty-project-bot

Copy link
Copy Markdown
Contributor

Auto-port PR for 4.1: #16838

@github-actions github-actions Bot removed the needs-cherry-pick-4.1 This PR should be cherry-picked to 4.1 once merged. label May 20, 2026
@netty-project-bot

Copy link
Copy Markdown
Contributor

Auto-port PR for 5.0: #16839

@github-actions github-actions Bot removed the needs-cherry-pick-5.0 This PR should be cherry-picked to 5.0 once merged. label May 20, 2026
@chrisvest

Copy link
Copy Markdown
Member

@jbertram Yeah, I will do a release later today.

@jbertram

Copy link
Copy Markdown
Contributor

@chrisvest, many thanks!

chrisvest pushed a commit that referenced this pull request May 20, 2026
…ay (#16838)

Auto-port of #16787 to 4.1
Cherry-picked commit: 72df658

---
## Problem

The MQTT decoder can reject valid packets after the CVE-2026-44248 fix
when several MQTT packets are present in the same cumulation buffer. If
the current packet's variable header needs a replay, the decoder
compares the total readable bytes in the buffer against
`maxBytesInMessage`, so later packets can make the current in-limit
packet look too large.

## Root Cause

`READ_VARIABLE_HEADER` recorded `buffer.readableBytes()` before decoding
the variable header. That value is the cumulation's total readable
bytes, not the current MQTT packet's declared remaining length. When
`decodeVariableHeader` throws `Signal.REPLAY`, the too-large decision
must be based on `bytesRemainingBeforeVariableHeader` for the current
packet.

## Fix

- Use `bytesRemainingBeforeVariableHeader` when deciding whether to
swallow `Signal.REPLAY` and raise `TooLongFrameException`.
- Continue replaying when the current packet is within
`maxBytesInMessage`, even if the cumulation contains additional bytes
for following packets.

## Tests Added

| Change Point | Test |
|-------------|------|
| Variable-header replay uses the current packet size instead of total
cumulation bytes for the too-long check |
`testPublishMessageIncompleteVariableHeaderDoesNotUseCumulationSizeForTooLongCheck()`
verifies an incomplete in-limit PUBLISH variable header with extra
cumulated PINGREQ packets does not emit an invalid message |
| Oversized current packets still fail during variable-header replay |
`testPublishMessageIncompleteVariableHeaderStillFailsWhenCurrentPacketTooLarge()`
verifies an incomplete PUBLISH whose own remaining length exceeds
`maxBytesInMessage` still emits a `TooLongFrameException` |

## Impact

This restores decoding for valid in-limit MQTT packets batched in the
same buffer while preserving the CVE fix: packets whose declared
remaining length exceeds `maxBytesInMessage` still fail with
`TooLongFrameException` even if variable-header decoding requests
replay.

Fixes #16776

Co-authored-by: Guimu <30684111+daguimu@users.noreply.github.com>
@daguimu daguimu deleted the fix/mqtt-cve-signal-check-16776 branch May 20, 2026 22:56
mergify Bot added a commit to ArcadeData/arcadedb that referenced this pull request May 24, 2026
…ip ci]

Bumps `netty.version` from 4.2.13.Final to 4.2.14.Final.
Updates `io.netty:netty-transport` from 4.2.13.Final to 4.2.14.Final
Release notes

*Sourced from [io.netty:netty-transport's releases](https://github.com/netty/netty/releases).*

> netty-4.2.14.Final
> ------------------
>
> What's Changed
> --------------
>
> * HTTP: Fix revapi failure introduced by 84530fa81e12dcd1d42310bb20c1385cb44128d8 by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16748](https://redirect.github.com/netty/netty/pull/16748)
> * HTTP: Re-add constructor to HttpProxyHandler that was removed by mistake by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16747](https://redirect.github.com/netty/netty/pull/16747)
> * Marshalling: Explicit document security requirements by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16752](https://redirect.github.com/netty/netty/pull/16752)
> * Fix io\_uring op completion TRACE logging by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16755](https://redirect.github.com/netty/netty/pull/16755)
> * Quic: Ensure writes are done before notify close promise of QuicheQui… by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16758](https://redirect.github.com/netty/netty/pull/16758)
> * Avoid re-parsing openssl key material with non-cached provider by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16759](https://redirect.github.com/netty/netty/pull/16759)
> * Pin HTTP/RTSP version + method normalization to Locale.US by [`@​daguimu`](https://github.com/daguimu) in [netty/netty#16765](https://redirect.github.com/netty/netty/pull/16765)
> * Fill MsgHdrMemoryArray#hdrs with null entry on release by [`@​tsegismont`](https://github.com/tsegismont) in [netty/netty#16764](https://redirect.github.com/netty/netty/pull/16764)
> * Revapi: Use default "oldVersion" by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16774](https://redirect.github.com/netty/netty/pull/16774)
> * Adaptive: Fix concurrency issue in adaptive allocator by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16767](https://redirect.github.com/netty/netty/pull/16767)
> * Auto-port 4.2: Make bulk byte moving in ByteBuf faster by [`@​netty-project-bot`](https://github.com/netty-project-bot) in [netty/netty#16781](https://redirect.github.com/netty/netty/pull/16781)
> * Pin multipart Content-Type / Content-Transfer-Encoding case folding to Locale.US by [`@​daguimu`](https://github.com/daguimu) in [netty/netty#16768](https://redirect.github.com/netty/netty/pull/16768)
> * Remove dead native declarations by [`@​pandareen`](https://github.com/pandareen) in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783)
> * Isolate tests that modify available Security providers by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16793](https://redirect.github.com/netty/netty/pull/16793)
> * Remove test annotations from a method that isn't a test by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16792](https://redirect.github.com/netty/netty/pull/16792)
> * Enable OpenSslCachingKeyMaterialProvider to evict stale entries after cert rotation by [`@​zhangweikop`](https://github.com/zhangweikop) in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523)
> * IoUring: extend user data from short to long by [`@​dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16682](https://redirect.github.com/netty/netty/pull/16682)
> * Revert CompositeByteBuf component search fast path by [`@​yawkat`](https://github.com/yawkat) in [netty/netty#16811](https://redirect.github.com/netty/netty/pull/16811)
> * HTTP2: Use 100 as default max concurrent streams setting by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16804](https://redirect.github.com/netty/netty/pull/16804)
> * Fix ResumptionController wrapping by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16815](https://redirect.github.com/netty/netty/pull/16815)
> * Resolve all localhost addresses without querying DNS servers by [`@​JulianVennen`](https://github.com/JulianVennen) in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749)
> * IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules are configured but remote peer is using ipv4 by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16803](https://redirect.github.com/netty/netty/pull/16803)
> * Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe by [`@​dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16788](https://redirect.github.com/netty/netty/pull/16788)
> * Route synchronous onLookupComplete exceptions via fireExceptionCaught by [`@​kwondh5217`](https://github.com/kwondh5217) in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794)
> * IoUring: Stop generic FileRegion drain loop when transferred() reaches count() by [`@​LuciferYang`](https://github.com/LuciferYang) in [netty/netty#16826](https://redirect.github.com/netty/netty/pull/16826)
> * MQTT: Allow MQTT 5 CONNECT with password only by [`@​shblue21`](https://github.com/shblue21) in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833)
> * Fix MQTT decoder size check after variable header replay by [`@​daguimu`](https://github.com/daguimu) in [netty/netty#16787](https://redirect.github.com/netty/netty/pull/16787)
>
> New Contributors
> ----------------
>
> * [`@​pandareen`](https://github.com/pandareen) made their first contribution in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783)
> * [`@​zhangweikop`](https://github.com/zhangweikop) made their first contribution in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523)
> * [`@​JulianVennen`](https://github.com/JulianVennen) made their first contribution in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749)
> * [`@​kwondh5217`](https://github.com/kwondh5217) made their first contribution in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794)
> * [`@​shblue21`](https://github.com/shblue21) made their first contribution in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833)
>
> **Full Changelog**: <netty/netty@netty-4.2.13.Final...netty-4.2.14.Final>


Commits

* [`0a60b75`](netty/netty@0a60b75) [maven-release-plugin] prepare release netty-4.2.14.Final
* [`72df658`](netty/netty@72df658) Fix MQTT decoder size check after variable header replay ([#16787](https://redirect.github.com/netty/netty/issues/16787))
* [`7125dba`](netty/netty@7125dba) MQTT: Allow MQTT 5 CONNECT with password only ([#16833](https://redirect.github.com/netty/netty/issues/16833))
* [`9e19320`](netty/netty@9e19320) IoUring: Stop generic FileRegion drain loop when transferred() reaches count(...
* [`4ce9f17`](netty/netty@4ce9f17) Route synchronous onLookupComplete exceptions via fireExceptionCaught ([#16794](https://redirect.github.com/netty/netty/issues/16794))
* [`f7b1b7d`](netty/netty@f7b1b7d) Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe...
* [`0ccb265`](netty/netty@0ccb265) IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules ...
* [`a6aeb6d`](netty/netty@a6aeb6d) Resolve all localhost addresses without querying DNS servers ([#16749](https://redirect.github.com/netty/netty/issues/16749))
* [`c328ba2`](netty/netty@c328ba2) Fix ResumptionController wrapping ([#16815](https://redirect.github.com/netty/netty/issues/16815))
* [`bc5862b`](netty/netty@bc5862b) HTTP2: Use 100 as default max concurrent streams setting ([#16804](https://redirect.github.com/netty/netty/issues/16804))
* Additional commits viewable in [compare view](netty/netty@netty-4.2.13.Final...netty-4.2.14.Final)
  
Updates `io.netty:netty-codec` from 4.2.13.Final to 4.2.14.Final
Release notes

*Sourced from [io.netty:netty-codec's releases](https://github.com/netty/netty/releases).*

> netty-4.2.14.Final
> ------------------
>
> What's Changed
> --------------
>
> * HTTP: Fix revapi failure introduced by 84530fa81e12dcd1d42310bb20c1385cb44128d8 by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16748](https://redirect.github.com/netty/netty/pull/16748)
> * HTTP: Re-add constructor to HttpProxyHandler that was removed by mistake by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16747](https://redirect.github.com/netty/netty/pull/16747)
> * Marshalling: Explicit document security requirements by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16752](https://redirect.github.com/netty/netty/pull/16752)
> * Fix io\_uring op completion TRACE logging by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16755](https://redirect.github.com/netty/netty/pull/16755)
> * Quic: Ensure writes are done before notify close promise of QuicheQui… by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16758](https://redirect.github.com/netty/netty/pull/16758)
> * Avoid re-parsing openssl key material with non-cached provider by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16759](https://redirect.github.com/netty/netty/pull/16759)
> * Pin HTTP/RTSP version + method normalization to Locale.US by [`@​daguimu`](https://github.com/daguimu) in [netty/netty#16765](https://redirect.github.com/netty/netty/pull/16765)
> * Fill MsgHdrMemoryArray#hdrs with null entry on release by [`@​tsegismont`](https://github.com/tsegismont) in [netty/netty#16764](https://redirect.github.com/netty/netty/pull/16764)
> * Revapi: Use default "oldVersion" by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16774](https://redirect.github.com/netty/netty/pull/16774)
> * Adaptive: Fix concurrency issue in adaptive allocator by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16767](https://redirect.github.com/netty/netty/pull/16767)
> * Auto-port 4.2: Make bulk byte moving in ByteBuf faster by [`@​netty-project-bot`](https://github.com/netty-project-bot) in [netty/netty#16781](https://redirect.github.com/netty/netty/pull/16781)
> * Pin multipart Content-Type / Content-Transfer-Encoding case folding to Locale.US by [`@​daguimu`](https://github.com/daguimu) in [netty/netty#16768](https://redirect.github.com/netty/netty/pull/16768)
> * Remove dead native declarations by [`@​pandareen`](https://github.com/pandareen) in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783)
> * Isolate tests that modify available Security providers by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16793](https://redirect.github.com/netty/netty/pull/16793)
> * Remove test annotations from a method that isn't a test by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16792](https://redirect.github.com/netty/netty/pull/16792)
> * Enable OpenSslCachingKeyMaterialProvider to evict stale entries after cert rotation by [`@​zhangweikop`](https://github.com/zhangweikop) in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523)
> * IoUring: extend user data from short to long by [`@​dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16682](https://redirect.github.com/netty/netty/pull/16682)
> * Revert CompositeByteBuf component search fast path by [`@​yawkat`](https://github.com/yawkat) in [netty/netty#16811](https://redirect.github.com/netty/netty/pull/16811)
> * HTTP2: Use 100 as default max concurrent streams setting by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16804](https://redirect.github.com/netty/netty/pull/16804)
> * Fix ResumptionController wrapping by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16815](https://redirect.github.com/netty/netty/pull/16815)
> * Resolve all localhost addresses without querying DNS servers by [`@​JulianVennen`](https://github.com/JulianVennen) in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749)
> * IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules are configured but remote peer is using ipv4 by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16803](https://redirect.github.com/netty/netty/pull/16803)
> * Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe by [`@​dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16788](https://redirect.github.com/netty/netty/pull/16788)
> * Route synchronous onLookupComplete exceptions via fireExceptionCaught by [`@​kwondh5217`](https://github.com/kwondh5217) in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794)
> * IoUring: Stop generic FileRegion drain loop when transferred() reaches count() by [`@​LuciferYang`](https://github.com/LuciferYang) in [netty/netty#16826](https://redirect.github.com/netty/netty/pull/16826)
> * MQTT: Allow MQTT 5 CONNECT with password only by [`@​shblue21`](https://github.com/shblue21) in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833)
> * Fix MQTT decoder size check after variable header replay by [`@​daguimu`](https://github.com/daguimu) in [netty/netty#16787](https://redirect.github.com/netty/netty/pull/16787)
>
> New Contributors
> ----------------
>
> * [`@​pandareen`](https://github.com/pandareen) made their first contribution in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783)
> * [`@​zhangweikop`](https://github.com/zhangweikop) made their first contribution in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523)
> * [`@​JulianVennen`](https://github.com/JulianVennen) made their first contribution in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749)
> * [`@​kwondh5217`](https://github.com/kwondh5217) made their first contribution in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794)
> * [`@​shblue21`](https://github.com/shblue21) made their first contribution in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833)
>
> **Full Changelog**: <netty/netty@netty-4.2.13.Final...netty-4.2.14.Final>


Commits

* [`0a60b75`](netty/netty@0a60b75) [maven-release-plugin] prepare release netty-4.2.14.Final
* [`72df658`](netty/netty@72df658) Fix MQTT decoder size check after variable header replay ([#16787](https://redirect.github.com/netty/netty/issues/16787))
* [`7125dba`](netty/netty@7125dba) MQTT: Allow MQTT 5 CONNECT with password only ([#16833](https://redirect.github.com/netty/netty/issues/16833))
* [`9e19320`](netty/netty@9e19320) IoUring: Stop generic FileRegion drain loop when transferred() reaches count(...
* [`4ce9f17`](netty/netty@4ce9f17) Route synchronous onLookupComplete exceptions via fireExceptionCaught ([#16794](https://redirect.github.com/netty/netty/issues/16794))
* [`f7b1b7d`](netty/netty@f7b1b7d) Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe...
* [`0ccb265`](netty/netty@0ccb265) IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules ...
* [`a6aeb6d`](netty/netty@a6aeb6d) Resolve all localhost addresses without querying DNS servers ([#16749](https://redirect.github.com/netty/netty/issues/16749))
* [`c328ba2`](netty/netty@c328ba2) Fix ResumptionController wrapping ([#16815](https://redirect.github.com/netty/netty/issues/16815))
* [`bc5862b`](netty/netty@bc5862b) HTTP2: Use 100 as default max concurrent streams setting ([#16804](https://redirect.github.com/netty/netty/issues/16804))
* Additional commits viewable in [compare view](netty/netty@netty-4.2.13.Final...netty-4.2.14.Final)
  
Updates `io.netty:netty-handler` from 4.2.13.Final to 4.2.14.Final
Release notes

*Sourced from [io.netty:netty-handler's releases](https://github.com/netty/netty/releases).*

> netty-4.2.14.Final
> ------------------
>
> What's Changed
> --------------
>
> * HTTP: Fix revapi failure introduced by 84530fa81e12dcd1d42310bb20c1385cb44128d8 by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16748](https://redirect.github.com/netty/netty/pull/16748)
> * HTTP: Re-add constructor to HttpProxyHandler that was removed by mistake by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16747](https://redirect.github.com/netty/netty/pull/16747)
> * Marshalling: Explicit document security requirements by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16752](https://redirect.github.com/netty/netty/pull/16752)
> * Fix io\_uring op completion TRACE logging by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16755](https://redirect.github.com/netty/netty/pull/16755)
> * Quic: Ensure writes are done before notify close promise of QuicheQui… by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16758](https://redirect.github.com/netty/netty/pull/16758)
> * Avoid re-parsing openssl key material with non-cached provider by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16759](https://redirect.github.com/netty/netty/pull/16759)
> * Pin HTTP/RTSP version + method normalization to Locale.US by [`@​daguimu`](https://github.com/daguimu) in [netty/netty#16765](https://redirect.github.com/netty/netty/pull/16765)
> * Fill MsgHdrMemoryArray#hdrs with null entry on release by [`@​tsegismont`](https://github.com/tsegismont) in [netty/netty#16764](https://redirect.github.com/netty/netty/pull/16764)
> * Revapi: Use default "oldVersion" by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16774](https://redirect.github.com/netty/netty/pull/16774)
> * Adaptive: Fix concurrency issue in adaptive allocator by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16767](https://redirect.github.com/netty/netty/pull/16767)
> * Auto-port 4.2: Make bulk byte moving in ByteBuf faster by [`@​netty-project-bot`](https://github.com/netty-project-bot) in [netty/netty#16781](https://redirect.github.com/netty/netty/pull/16781)
> * Pin multipart Content-Type / Content-Transfer-Encoding case folding to Locale.US by [`@​daguimu`](https://github.com/daguimu) in [netty/netty#16768](https://redirect.github.com/netty/netty/pull/16768)
> * Remove dead native declarations by [`@​pandareen`](https://github.com/pandareen) in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783)
> * Isolate tests that modify available Security providers by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16793](https://redirect.github.com/netty/netty/pull/16793)
> * Remove test annotations from a method that isn't a test by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16792](https://redirect.github.com/netty/netty/pull/16792)
> * Enable OpenSslCachingKeyMaterialProvider to evict stale entries after cert rotation by [`@​zhangweikop`](https://github.com/zhangweikop) in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523)
> * IoUring: extend user data from short to long by [`@​dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16682](https://redirect.github.com/netty/netty/pull/16682)
> * Revert CompositeByteBuf component search fast path by [`@​yawkat`](https://github.com/yawkat) in [netty/netty#16811](https://redirect.github.com/netty/netty/pull/16811)
> * HTTP2: Use 100 as default max concurrent streams setting by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16804](https://redirect.github.com/netty/netty/pull/16804)
> * Fix ResumptionController wrapping by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16815](https://redirect.github.com/netty/netty/pull/16815)
> * Resolve all localhost addresses without querying DNS servers by [`@​JulianVennen`](https://github.com/JulianVennen) in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749)
> * IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules are configured but remote peer is using ipv4 by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16803](https://redirect.github.com/netty/netty/pull/16803)
> * Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe by [`@​dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16788](https://redirect.github.com/netty/netty/pull/16788)
> * Route synchronous onLookupComplete exceptions via fireExceptionCaught by [`@​kwondh5217`](https://github.com/kwondh5217) in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794)
> * IoUring: Stop generic FileRegion drain loop when transferred() reaches count() by [`@​LuciferYang`](https://github.com/LuciferYang) in [netty/netty#16826](https://redirect.github.com/netty/netty/pull/16826)
> * MQTT: Allow MQTT 5 CONNECT with password only by [`@​shblue21`](https://github.com/shblue21) in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833)
> * Fix MQTT decoder size check after variable header replay by [`@​daguimu`](https://github.com/daguimu) in [netty/netty#16787](https://redirect.github.com/netty/netty/pull/16787)
>
> New Contributors
> ----------------
>
> * [`@​pandareen`](https://github.com/pandareen) made their first contribution in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783)
> * [`@​zhangweikop`](https://github.com/zhangweikop) made their first contribution in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523)
> * [`@​JulianVennen`](https://github.com/JulianVennen) made their first contribution in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749)
> * [`@​kwondh5217`](https://github.com/kwondh5217) made their first contribution in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794)
> * [`@​shblue21`](https://github.com/shblue21) made their first contribution in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833)
>
> **Full Changelog**: <netty/netty@netty-4.2.13.Final...netty-4.2.14.Final>


Commits

* [`0a60b75`](netty/netty@0a60b75) [maven-release-plugin] prepare release netty-4.2.14.Final
* [`72df658`](netty/netty@72df658) Fix MQTT decoder size check after variable header replay ([#16787](https://redirect.github.com/netty/netty/issues/16787))
* [`7125dba`](netty/netty@7125dba) MQTT: Allow MQTT 5 CONNECT with password only ([#16833](https://redirect.github.com/netty/netty/issues/16833))
* [`9e19320`](netty/netty@9e19320) IoUring: Stop generic FileRegion drain loop when transferred() reaches count(...
* [`4ce9f17`](netty/netty@4ce9f17) Route synchronous onLookupComplete exceptions via fireExceptionCaught ([#16794](https://redirect.github.com/netty/netty/issues/16794))
* [`f7b1b7d`](netty/netty@f7b1b7d) Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe...
* [`0ccb265`](netty/netty@0ccb265) IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules ...
* [`a6aeb6d`](netty/netty@a6aeb6d) Resolve all localhost addresses without querying DNS servers ([#16749](https://redirect.github.com/netty/netty/issues/16749))
* [`c328ba2`](netty/netty@c328ba2) Fix ResumptionController wrapping ([#16815](https://redirect.github.com/netty/netty/issues/16815))
* [`bc5862b`](netty/netty@bc5862b) HTTP2: Use 100 as default max concurrent streams setting ([#16804](https://redirect.github.com/netty/netty/issues/16804))
* Additional commits viewable in [compare view](netty/netty@netty-4.2.13.Final...netty-4.2.14.Final)
  
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
  
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot show  ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
mergify Bot added a commit to ArcadeData/arcadedb that referenced this pull request May 24, 2026
…l [skip ci]

Bumps [io.netty:netty-all](https://github.com/netty/netty) from 4.2.13.Final to 4.2.14.Final.
Release notes

*Sourced from [io.netty:netty-all's releases](https://github.com/netty/netty/releases).*

> netty-4.2.14.Final
> ------------------
>
> What's Changed
> --------------
>
> * HTTP: Fix revapi failure introduced by 84530fa81e12dcd1d42310bb20c1385cb44128d8 by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16748](https://redirect.github.com/netty/netty/pull/16748)
> * HTTP: Re-add constructor to HttpProxyHandler that was removed by mistake by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16747](https://redirect.github.com/netty/netty/pull/16747)
> * Marshalling: Explicit document security requirements by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16752](https://redirect.github.com/netty/netty/pull/16752)
> * Fix io\_uring op completion TRACE logging by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16755](https://redirect.github.com/netty/netty/pull/16755)
> * Quic: Ensure writes are done before notify close promise of QuicheQui… by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16758](https://redirect.github.com/netty/netty/pull/16758)
> * Avoid re-parsing openssl key material with non-cached provider by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16759](https://redirect.github.com/netty/netty/pull/16759)
> * Pin HTTP/RTSP version + method normalization to Locale.US by [`@​daguimu`](https://github.com/daguimu) in [netty/netty#16765](https://redirect.github.com/netty/netty/pull/16765)
> * Fill MsgHdrMemoryArray#hdrs with null entry on release by [`@​tsegismont`](https://github.com/tsegismont) in [netty/netty#16764](https://redirect.github.com/netty/netty/pull/16764)
> * Revapi: Use default "oldVersion" by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16774](https://redirect.github.com/netty/netty/pull/16774)
> * Adaptive: Fix concurrency issue in adaptive allocator by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16767](https://redirect.github.com/netty/netty/pull/16767)
> * Auto-port 4.2: Make bulk byte moving in ByteBuf faster by [`@​netty-project-bot`](https://github.com/netty-project-bot) in [netty/netty#16781](https://redirect.github.com/netty/netty/pull/16781)
> * Pin multipart Content-Type / Content-Transfer-Encoding case folding to Locale.US by [`@​daguimu`](https://github.com/daguimu) in [netty/netty#16768](https://redirect.github.com/netty/netty/pull/16768)
> * Remove dead native declarations by [`@​pandareen`](https://github.com/pandareen) in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783)
> * Isolate tests that modify available Security providers by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16793](https://redirect.github.com/netty/netty/pull/16793)
> * Remove test annotations from a method that isn't a test by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16792](https://redirect.github.com/netty/netty/pull/16792)
> * Enable OpenSslCachingKeyMaterialProvider to evict stale entries after cert rotation by [`@​zhangweikop`](https://github.com/zhangweikop) in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523)
> * IoUring: extend user data from short to long by [`@​dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16682](https://redirect.github.com/netty/netty/pull/16682)
> * Revert CompositeByteBuf component search fast path by [`@​yawkat`](https://github.com/yawkat) in [netty/netty#16811](https://redirect.github.com/netty/netty/pull/16811)
> * HTTP2: Use 100 as default max concurrent streams setting by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16804](https://redirect.github.com/netty/netty/pull/16804)
> * Fix ResumptionController wrapping by [`@​chrisvest`](https://github.com/chrisvest) in [netty/netty#16815](https://redirect.github.com/netty/netty/pull/16815)
> * Resolve all localhost addresses without querying DNS servers by [`@​JulianVennen`](https://github.com/JulianVennen) in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749)
> * IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules are configured but remote peer is using ipv4 by [`@​normanmaurer`](https://github.com/normanmaurer) in [netty/netty#16803](https://redirect.github.com/netty/netty/pull/16803)
> * Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe by [`@​dreamlike-ocean`](https://github.com/dreamlike-ocean) in [netty/netty#16788](https://redirect.github.com/netty/netty/pull/16788)
> * Route synchronous onLookupComplete exceptions via fireExceptionCaught by [`@​kwondh5217`](https://github.com/kwondh5217) in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794)
> * IoUring: Stop generic FileRegion drain loop when transferred() reaches count() by [`@​LuciferYang`](https://github.com/LuciferYang) in [netty/netty#16826](https://redirect.github.com/netty/netty/pull/16826)
> * MQTT: Allow MQTT 5 CONNECT with password only by [`@​shblue21`](https://github.com/shblue21) in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833)
> * Fix MQTT decoder size check after variable header replay by [`@​daguimu`](https://github.com/daguimu) in [netty/netty#16787](https://redirect.github.com/netty/netty/pull/16787)
>
> New Contributors
> ----------------
>
> * [`@​pandareen`](https://github.com/pandareen) made their first contribution in [netty/netty#16783](https://redirect.github.com/netty/netty/pull/16783)
> * [`@​zhangweikop`](https://github.com/zhangweikop) made their first contribution in [netty/netty#16523](https://redirect.github.com/netty/netty/pull/16523)
> * [`@​JulianVennen`](https://github.com/JulianVennen) made their first contribution in [netty/netty#16749](https://redirect.github.com/netty/netty/pull/16749)
> * [`@​kwondh5217`](https://github.com/kwondh5217) made their first contribution in [netty/netty#16794](https://redirect.github.com/netty/netty/pull/16794)
> * [`@​shblue21`](https://github.com/shblue21) made their first contribution in [netty/netty#16833](https://redirect.github.com/netty/netty/pull/16833)
>
> **Full Changelog**: <netty/netty@netty-4.2.13.Final...netty-4.2.14.Final>


Commits

* [`0a60b75`](netty/netty@0a60b75) [maven-release-plugin] prepare release netty-4.2.14.Final
* [`72df658`](netty/netty@72df658) Fix MQTT decoder size check after variable header replay ([#16787](https://redirect.github.com/netty/netty/issues/16787))
* [`7125dba`](netty/netty@7125dba) MQTT: Allow MQTT 5 CONNECT with password only ([#16833](https://redirect.github.com/netty/netty/issues/16833))
* [`9e19320`](netty/netty@9e19320) IoUring: Stop generic FileRegion drain loop when transferred() reaches count(...
* [`4ce9f17`](netty/netty@4ce9f17) Route synchronous onLookupComplete exceptions via fireExceptionCaught ([#16794](https://redirect.github.com/netty/netty/issues/16794))
* [`f7b1b7d`](netty/netty@f7b1b7d) Fix memoryAddress() for direct ByteBuffers wrapped by Unpooled without Unsafe...
* [`0ccb265`](netty/netty@0ccb265) IpFilter: Fix ClassCastException caused by IpSubnetFilter if only ipv6 rules ...
* [`a6aeb6d`](netty/netty@a6aeb6d) Resolve all localhost addresses without querying DNS servers ([#16749](https://redirect.github.com/netty/netty/issues/16749))
* [`c328ba2`](netty/netty@c328ba2) Fix ResumptionController wrapping ([#16815](https://redirect.github.com/netty/netty/issues/16815))
* [`bc5862b`](netty/netty@bc5862b) HTTP2: Use 100 as default max concurrent streams setting ([#16804](https://redirect.github.com/netty/netty/issues/16804))
* Additional commits viewable in [compare view](netty/netty@netty-4.2.13.Final...netty-4.2.14.Final)
  
[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility\_score?dependency-name=io.netty:netty-all&package-manager=maven&previous-version=4.2.13.Final&new-version=4.2.14.Final)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
  
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot show  ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
ViacheslavKlimov added a commit to thingsboard/thingsboard that referenced this pull request May 28, 2026
Netty 4.1.133.Final introduced a regression in MqttDecoder while fixing
CVE-2026-44248: when multiple MQTT packets are present in the same
cumulation buffer, the per-message size check used the total buffer size
instead of the current packet's declared remaining length. Valid in-limit
packets get rejected with TooLongFrameException("message length exceeds
65536: <small number>"). Fixed upstream by netty/netty#16787 and ported
to 4.1 as netty/netty@30f8f284db, released in 4.1.134.Final.
chrisvest pushed a commit that referenced this pull request Jun 5, 2026
### Motivation

#16787 fixed the `READ_VARIABLE_HEADER` too-long check on the **4.2**
branch by replacing a `ReplayingDecoderByteBuf.readableBytes()` probe
with the message size declared by the fixed header. That fix was
auto-ported to 4.1 in #16838, **but a later CVE-2026-44248 security
merge re-introduced the broken code on 4.1**, so the 4.1 branch still
carries the regression:

```java
int initialAvailableBytes = buffer.readableBytes();
...
if (initialAvailableBytes < maxBytesInMessage) {
    throw signal;   // REPLAY
} else {
    bailOut = true; // too long
}
```

Because `MqttDecoder extends ReplayingDecoder`, `buffer` is a
`ReplayingDecoderByteBuf` whose `readableBytes()` returns
`Integer.MAX_VALUE - readerIndex` rather than the bytes actually
buffered. With the default `maxBytesInMessage` of `8092`, the
`initialAvailableBytes < maxBytesInMessage` check is therefore
effectively always false. So when `decodeVariableHeader` asks for a
`REPLAY` because the variable header has not fully arrived yet, the
decoder takes the `bailOut` branch and rejects the message with a
`TooLongFrameException` instead of waiting for the rest — a valid
message whose variable header is split across reads is dropped.

### Modification

Re-apply the #16787 fix on 4.1: drop the `initialAvailableBytes` /
`readableBytes()` probe and decide based on
`bytesRemainingBeforeVariableHeader` (the remaining length declared by
the fixed header). A genuinely oversized message is still rejected by
the existing `bytesRemainingBeforeVariableHeader > maxBytesInMessage`
check; an incomplete one now correctly `REPLAY`s.

### Result

A message whose variable header arrives in chunks is decoded once
complete, instead of being rejected as too long, while declared-oversize
messages still fail with `TooLongFrameException`. The two regression
tests from #16787 are ported here. All `codec-mqtt` tests pass locally.

Note: this targets **4.1 only** and intentionally carries no cherry-pick
label — 4.2 already has the fix via #16787. Found while addressing
@chrisvest's review comment on #16813 about the same `readableBytes()`
antipattern.
chrisvest pushed a commit that referenced this pull request Jun 5, 2026
)

Motivation:

The CVE-2026-44248 fix in 82f47fa added
a guard at the top of `decodeProperties` to trigger an early REPLAY when
the cumulation buffer did not yet have the full properties block:

```java
if (buffer.readableBytes() < totalPropertiesLength) {
    buffer.readSlice(totalPropertiesLength);
}
```

Because `MqttDecoder` extends `ReplayingDecoder`, the buffer passed to
`decodeProperties` is a `ReplayingDecoderByteBuf` whose
`readableBytes()` returns `Integer.MAX_VALUE - readerIndex` rather than
the actual number of bytes available (see
`ReplayingDecoderByteBuf.readableBytes()`). The `if`-condition is
therefore false in practice and the `readSlice()` call never executes,
so the early-REPLAY optimization is effectively dead code. When the
properties block arrives in chunks the decoder still falls back to
partial parsing followed by a mid-loop REPLAY, which defeats the
optimization's intent on slow streams.

Modification:

Replace the broken `readableBytes()` check with a `getByte()` probe at
`buffer.readerIndex() + totalPropertiesLength - 1`.
`ReplayingDecoderByteBuf.checkIndex` throws `Signal.REPLAY` when `index
+ 1 > writerIndex` — i.e. exactly when the cumulation buffer does not
yet hold the full properties block. The call has no side effect on
`readerIndex`, so subsequent parsing is unchanged once the data arrives.
A `totalPropertiesLength > 0` guard skips the probe when there are no
properties.

Result:

The early-REPLAY guard now actually fires when properties data is
incomplete, restoring the CVE-2026-44248 fix's intent of avoiding
repeated partial-properties parsing on slow streams. No semantic change
on the happy path; all 107 existing `codec-mqtt` tests pass locally.

Note: this is complementary to #16787, which addresses the *outer*
variable-header REPLAY handling broken by the same CVE patch (same
`buffer.readableBytes()` antipattern in a ReplayingDecoder context).
Both fixes are independent and can land in either order; together they
restore the optimization the CVE-2026-44248 fix originally aimed for.
chrisvest pushed a commit that referenced this pull request Jun 5, 2026
…ually fire (#16919)

Auto-port of #16813 to 4.2
Cherry-picked commit: 2d781e2

---
Motivation:

The CVE-2026-44248 fix in 82f47fa added
a guard at the top of `decodeProperties` to trigger an early REPLAY when
the cumulation buffer did not yet have the full properties block:

```java
if (buffer.readableBytes() < totalPropertiesLength) {
    buffer.readSlice(totalPropertiesLength);
}
```

Because `MqttDecoder` extends `ReplayingDecoder`, the buffer passed to
`decodeProperties` is a `ReplayingDecoderByteBuf` whose
`readableBytes()` returns `Integer.MAX_VALUE - readerIndex` rather than
the actual number of bytes available (see
`ReplayingDecoderByteBuf.readableBytes()`). The `if`-condition is
therefore false in practice and the `readSlice()` call never executes,
so the early-REPLAY optimization is effectively dead code. When the
properties block arrives in chunks the decoder still falls back to
partial parsing followed by a mid-loop REPLAY, which defeats the
optimization's intent on slow streams.

Modification:

Replace the broken `readableBytes()` check with a `getByte()` probe at
`buffer.readerIndex() + totalPropertiesLength - 1`.
`ReplayingDecoderByteBuf.checkIndex` throws `Signal.REPLAY` when `index
+ 1 > writerIndex` — i.e. exactly when the cumulation buffer does not
yet hold the full properties block. The call has no side effect on
`readerIndex`, so subsequent parsing is unchanged once the data arrives.
A `totalPropertiesLength > 0` guard skips the probe when there are no
properties.

Result:

The early-REPLAY guard now actually fires when properties data is
incomplete, restoring the CVE-2026-44248 fix's intent of avoiding
repeated partial-properties parsing on slow streams. No semantic change
on the happy path; all 107 existing `codec-mqtt` tests pass locally.

Note: this is complementary to #16787, which addresses the *outer*
variable-header REPLAY handling broken by the same CVE patch (same
`buffer.readableBytes()` antipattern in a ReplayingDecoder context).
Both fixes are independent and can land in either order; together they
restore the optimization the CVE-2026-44248 fix originally aimed for.

Co-authored-by: Guimu <30684111+daguimu@users.noreply.github.com>
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.

The fix for CVE-2026-44248 breaks MQTT decoding

4 participants