Decoder::decode()
says an Err informs Framed
that the stream should be terminated, but Framed
doesn't terminate
#3976
Labels
A-tokio-util
Area: The tokio-util crate
C-bug
Category: This is a bug.
E-help-wanted
Call for participation: Help is requested to fix this issue.
E-medium
Call for participation: Experience needed to fix: Medium / intermediate
M-codec
Module: tokio-util/codec
Version
tokio-util v0.6.7
Platform
Darwin My-Computer 20.5.0 Darwin Kernel Version 20.5.0: Sat May 8 05:10:33 PDT 2021; root:xnu-7195.121.3~9/RELEASE_X86_64 x86_64
Description
tokio_util::codec::FramedRead
will happily continue trying to decode a stream after the associatedtokio_util::codec::Decoder
implementation returnsErr
fromDecoder::decode()
orDecoder::decode_eof()
. This happens in spite of the documentation onDecoder::decode()
:(
decode_eof()
does not document the semantics of returning an error but it's safe to assume it's the same asdecode()
).Looking at
<FramedImpl as Stream>::poll_next()
, it returns theErr
to its caller without modifying its state:tokio/tokio-util/src/codec/framed_impl.rs
Lines 168 to 179 in 2087f3e
This means that if the
decode()
method returns anErr
without consuming any bytes from the buffer, a simple loop like the following will go into a tight infinite loop:And if a
Decoder
impl can return recoverable errors, and does so from thedecode()
method instead of moving them into theItem
, then that lends itself to the following loop:It's really easy to write this loop, especially if you haven't carefully read all of the associated documentation, and you won't realize what happened until you hit a nonrecoverable error.
If
Framed
actually did what theDecoder::decode()
documentation suggests and moved to a terminal state upon encountering anErr
, then these loops would instantly go from an infinite loop to one that logs an error and terminates. This would also strongly encourageDecoder
impls that can return recoverable errors to make that distinction properly in its return type.Optionally, if someone is using a non-conforming
Decoder
impl that mixes recoverable and non-recoverable errors together and the calling code wants to intelligently handle that,Framed
could offer a method to recover from the terminal state.This behavior change should probably be considered a breaking change, but I could make the argument that it's a bugfix (makes behavior conform to documentation) and that it's an important safety improvement for existing code (turns infinite loops into finite ones).
The text was updated successfully, but these errors were encountered: