Skip to content

Commit 9f40642

Browse files
committed
Change behaviour in corner case of empty decompression input
The incremental decompressor would ask for input again after being given empty initially. It should just ask once. This case is always an error anyway, but the decompressor should never ask for more input after having been given the end of input indication.
1 parent 77b8771 commit 9f40642

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

Codec/Compression/Zlib/Internal.hs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,8 +595,14 @@ decompressStream format (DecompressParams bits initChunkSize mdict allMembers)
595595
else assert outputBufferFull $
596596
Stream.inflateInit format bits
597597
case chunk of
598-
_ | S.null chunk ->
599-
fillBuffers 4 --always an error anyway
598+
_ | S.null chunk -> do
599+
-- special case to avoid demanding more input again
600+
-- always an error anyway
601+
when outputBufferFull $ do
602+
let outChunkSize = 1
603+
outFPtr <- Stream.unsafeLiftIO (S.mallocByteString outChunkSize)
604+
Stream.pushOutputBuffer outFPtr 0 outChunkSize
605+
drainBuffers True
600606

601607
S.PS inFPtr offset length -> do
602608
Stream.pushInputBuffer inFPtr offset length

test/Test.hs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ main = defaultMain $
5050
testCase "handle trailing data" test_trailing_data,
5151
testCase "multiple gzip members" test_multiple_members,
5252
testCase "check small input chunks" test_small_chunks,
53+
testCase "check empty input" test_empty,
5354
testCase "check exception raised" test_exception
5455
]
5556
]
@@ -244,6 +245,20 @@ test_small_chunks = do
244245
compressedFile <- readSampleData "hello.gz"
245246
(GZip.decompress . smallChunks) compressedFile @?= GZip.decompress compressedFile
246247

248+
test_empty :: Assertion
249+
test_empty = do
250+
-- Regression test to make sure we only ask for input once in the case of
251+
-- initially empty input. We previously asked for input twice before
252+
-- returning the error.
253+
let decomp = decompressIO zlibFormat defaultDecompressParams
254+
case decomp of
255+
DecompressInputRequired next -> do
256+
decomp' <- next BS.empty
257+
case decomp' of
258+
DecompressStreamError TruncatedInput -> return ()
259+
_ -> assertFailure "expected truncated error"
260+
261+
_ -> assertFailure "expected input"
247262

248263
test_exception :: Assertion
249264
test_exception =

0 commit comments

Comments
 (0)