k0001 / pipes-binary

Encode and decode binary streams using the pipes and binary libraries.
Other
7 stars 12 forks source link

Decoding fails when the stream is a single empty chunk #24

Closed Gabriella439 closed 8 years ago

Gabriella439 commented 8 years ago

Here is the reproducing test case that causes the failure:

import Control.Exception (throwIO)
import Data.ByteString (ByteString)
import Lens.Simple (view)
import Pipes (Producer, for, liftIO, yield, (>->))
import Pipes.Binary (DecodingError)

import qualified Data.ByteString as ByteString
import qualified Pipes
import qualified Pipes.Binary
import qualified Pipes.Prelude

p   :: Monad m
    => Producer Int m (Either (DecodingError, Producer ByteString m ()) ())
p = view Pipes.Binary.decoded (yield ByteString.empty)

main = do
    x <- Pipes.runEffect (p >-> Pipes.Prelude.print)
    case x of
        Left (err, _) -> throwIO err
        Right      r  -> return  r

The above program fails with:

repro: DecodingError {deConsumed = 0, deMessage = "not enough bytes"}

The root of the problem is that the decoded function uses Pipes.next to test if the stream is empty, but this does not account for the stream possibly having empty chunks remaining.

k0001 commented 8 years ago

Thank you Gabriel. I'm afraid I won't be able to look at this until Monday, though. On Feb 13, 2016 4:01 AM, "Gabriel Gonzalez" notifications@github.com wrote:

Here is the reproducing test case that causes the failure:

import Control.Exception (throwIO)import Data.ByteString (ByteString)import Lens.Simple (view)import Pipes (Producer, for, liftIO, yield, (>->))import Pipes.Binary (DecodingError) import qualified Data.ByteString as ByteStringimport qualified Pipesimport qualified Pipes.Binaryimport qualified Pipes.Prelude p :: Monad m => Producer Int m (Either (DecodingError, Producer ByteString m ()) ()) p = view Pipes.Binary.decoded (yield ByteString.empty)

main = do x <- Pipes.runEffect (p >-> Pipes.Prelude.print) case x of Left (err, _) -> throwIO err Right r -> return r

The above program fails with:

repro: DecodingError {deConsumed = 0, deMessage = "not enough bytes"}

The root of the problem is that the decoded function uses Pipes.next to test if the stream is empty, but this does not account for the stream possibly having empty chunks remaining.

— Reply to this email directly or view it on GitHub https://github.com/k0001/pipes-binary/issues/24.

k0001 commented 8 years ago

Thank you @Gabriel439, this is in Hackage now as pipes-binary-0.4.1. I changed your implementation a bit to mimic what pipes-attoparsec is already doing to deal with this, only for consistency. I included the test case you submitted.