Skip to content

Return a decode result from Buffer::copy - #103

Merged
flamble merged 1 commit into
bloomberg:mainfrom
flamble:improve-decoding
Nov 2, 2026
Merged

flamble merged 1 commit into
bloomberg:mainfrom
flamble:improve-decoding

Conversation

@flamble

@flamble flamble commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Problem statement

Buffer::copy relied on BSLS_ASSERT to confirm enough bytes remained before its memcpy. Where that assert is compiled out a short buffer read past the end of the backing data; where it is enabled a truncated frame aborted the process. Neither is a reasonable response to bytes that arrive off the wire.

Proposed changes

Give copy an out parameter and a bool result, so a caller cannot go on to use a value that was never read. The destination must be exactly as wide as the wire type, checked at compile time, so naming the wrong type can neither truncate the value nor leave the read position part way through a field. Buffer::consume truncates to the bytes available.

Every decoder in rmqamqpt propagates that result, so a truncated payload becomes a decode failure, which Framer::appendFrame already reports to Connection as a channel exception. ConfirmSelect::decode had no length check at all and is covered by the same change.

Three value level fixes in the decoders this rewrites:

  • AMQP packs consecutive bit fields into one octet. Those fields are read into a uint8_t and masked to the bit they occupy, rather than copied into a bool, which is undefined for a byte other than 0 or 1 and let a reserved bit decide the value.
  • The unsupported DECIMAL value reported success without consuming its five octets, leaving the rest of the field table to be read from the wrong offset. It is now consumed and left unset, which re-encodes as V, so republishing such headers drops the decimal.
  • Types::decodeTimestamp returns bool and uses the checked bdlt::EpochUtil::convertFromTimeT64 overload, whose unchecked counterpart has an undefined behaviour precondition that a broker supplied value can violate.

The rewritten BasicQoS::decode guard also drops a stale log message that named Connection.Tune.

`Buffer::copy` relied on `BSLS_ASSERT` to confirm enough bytes remained
before its `memcpy`. Where that assert is compiled out a short buffer
read past the end of the backing data; where it is enabled a truncated
frame aborted the process. Neither is a reasonable response to bytes
that arrive off the wire.

Give `copy` an out parameter and a `bool` result, so a caller cannot go
on to use a value that was never read. The destination must be exactly
as wide as the wire type, checked at compile time, so naming the wrong
type can neither truncate the value nor leave the read position part
way through a field. `Buffer::consume` truncates to the bytes
available.

Every decoder in `rmqamqpt` propagates that result, so a truncated
payload becomes a decode failure, which `Framer::appendFrame` already
reports to `Connection` as a channel exception. `ConfirmSelect::decode`
had no length check at all and is covered by the same change.

Three value level fixes in the decoders this rewrites:

- AMQP packs consecutive `bit` fields into one octet. Those fields are
  read into a `uint8_t` and masked to the bit they occupy, rather than
  copied into a `bool`, which is undefined for a byte other than 0 or 1
  and let a reserved bit decide the value.
- The unsupported `DECIMAL` value reported success without consuming
  its five octets, leaving the rest of the field table to be read from
  the wrong offset. It is now consumed and left unset, which re-encodes
  as `V`, so republishing such headers drops the decimal.
- `Types::decodeTimestamp` returns `bool` and uses the checked
  `bdlt::EpochUtil::convertFromTimeT64` overload, whose unchecked
  counterpart has an undefined behaviour precondition that a broker
  supplied value can violate.

The rewritten `BasicQoS::decode` guard also drops a stale log message
that named `Connection.Tune`.
@flamble
flamble marked this pull request as ready for review November 2, 2026 10:59
@flamble
flamble merged commit 98aae61 into bloomberg:main Nov 2, 2026
4 checks passed
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