LogicalReplicationParser::parse_wal_message(data: &[u8]) -> Result<StreamingReplicationMessage> and its sibling parse_wal_message_bytes(data: bytes::Bytes) both build a BufferReader internally and return only the parsed message. The reader knows how many bytes are still unread after a successful parse, but neither entry point exposes that count, so a caller that wants to reject a frame with trailing garbage (a valid Insert payload followed by [0xAA, 0xBB], for example) has no surface to do so.
A downstream pgoutput parser that previously errored on trailing bytes loses that check the moment it delegates to this API.
I intend therefore to add parse_wal_message_strict(&mut self, data: &[u8]) -> Result<StreamingReplicationMessage> that errors with a new ReplicationError::TrailingBytes { expected, actual } variant when BufferReader::remaining() is non-zero after parsing.
LogicalReplicationParser::parse_wal_message(data: &[u8]) -> Result<StreamingReplicationMessage>and its siblingparse_wal_message_bytes(data: bytes::Bytes)both build aBufferReaderinternally and return only the parsed message. The reader knows how many bytes are still unread after a successful parse, but neither entry point exposes that count, so a caller that wants to reject a frame with trailing garbage (a valid Insert payload followed by[0xAA, 0xBB], for example) has no surface to do so.A downstream pgoutput parser that previously errored on trailing bytes loses that check the moment it delegates to this API.
I intend therefore to add
parse_wal_message_strict(&mut self, data: &[u8]) -> Result<StreamingReplicationMessage>that errors with a newReplicationError::TrailingBytes { expected, actual }variant whenBufferReader::remaining()is non-zero after parsing.