diff --git a/src/decompression.jl b/src/decompression.jl index 1668752..6767634 100644 --- a/src/decompression.jl +++ b/src/decompression.jl @@ -76,7 +76,14 @@ function TranscodingStreams.process(codec::ZstdDecompressor, input::Memory, outp error[] = ErrorException("zstd error") return Δin, Δout, :error else - return Δin, Δout, code == 0 ? :end : :ok + if code == 0 + return Δin, Δout, :end + elseif input.size == 0 && code > 0 + error[] = ErrorException("zstd frame truncated. Expected at least $(code) more bytes") + return Δin, Δout, :error + else + return Δin, Δout, :ok + end end end diff --git a/test/runtests.jl b/test/runtests.jl index 0ca4e4b..ea8ab4b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,6 +3,8 @@ using Random using TranscodingStreams using Test +Random.seed!(1234) + @testset "Zstd Codec" begin codec = ZstdCompressor() @test codec isa ZstdCompressor @@ -20,6 +22,20 @@ using Test @test read(ZstdDecompressorStream(IOBuffer(data))) == b"foo" @test read(ZstdDecompressorStream(IOBuffer(vcat(data, data)))) == b"foofoo" + @testset "Truncated frames" begin + # issue #24 + @test_throws ErrorException transcode(ZstdDecompressor, UInt8[]) + for trial in 1:1000 + local uncompressed_data = rand(UInt8, rand(0:100)) + local compressed_data = transcode(ZstdCompressor, uncompressed_data) + local L = length(compressed_data) + for n in 0:L-1 + @test_throws ErrorException transcode(ZstdDecompressor, compressed_data[1:n]) + end + @test transcode(ZstdDecompressor, compressed_data) == uncompressed_data + end + end + @test ZstdCompressorStream <: TranscodingStreams.TranscodingStream @test ZstdDecompressorStream <: TranscodingStreams.TranscodingStream